Java Reference
In-Depth Information
7.3. Handling Abnormal Thread Termination
It is obvious when a single-threaded console application terminates due to an uncaught ex-
ception—the program stops running and produces a stack trace that is very different from
typical program output. Failure of a thread in a concurrent application is not always so ob-
vious. The stack trace may be printed on the console, but no one may be watching the con-
sole. Also, when a thread fails, the application may appear to continue to work, so its failure
could go unnoticed. Fortunately, there are means of both detecting and preventing threads
from “leaking” from an application.
The leading cause of premature thread death is RuntimeException . Because these ex-
ceptions indicate a programming error or other unrecoverable problem, they are generally not
caught. Instead they propagate all the way up the stack, at which point the default behavior is
to print a stack trace on the console and let the thread terminate.
The consequences of abnormal thread death range from benign to disastrous, depending on
the thread's role in the application. Losing a thread from a thread pool can have performance
consequences, but an application that runs well with a 50-thread pool will probably run fine
with a 49-thread pool too. But losing the event dispatch thread in a GUI application would
be quite noticeable—the application would stop processing events and the GUI would freeze.
OutOfTime on 124 showed a serious consequence of thread leakage: the service represen-
ted by the Timer is permanently out of commission.
Just about any code can throw a RuntimeException . Whenever you call another method,
you are taking a leap of faith that it will return normally or throw one of the checked excep-
tions its signature declares. The less familiar you are with the code being called, the more
skeptical you should be about its behavior.
Task-processing threads such as the worker threads in a thread pool or the Swing event dis-
patch thread spend their whole life calling unknown code through an abstraction barrier like
Runnable , and these threads should be very skeptical that the code they call will be well
behaved. It would be very bad if a service like the Swing event thread failed just because
some poorly written event handler threw a NullPointerException . Accordingly, these
facilities should call tasks within a try-catch block that catches unchecked exceptions, or
within a try-finally block to ensure that if the thread exits abnormally the framework is
informed of this and can take corrective action. This is one of the few times when you might
want to consider catching RuntimeException —when you are calling unknown, untrus-
ted code through an abstraction such as Runnable . [7]
Search WWH ::




Custom Search