Search This Blog

Saturday, June 14, 2008

ThreadDeath and Throwable

I was looking at some code recently and noticed that java.lang.Throwable was being caught around code doing some business processing. Catching Throwable or for that matter catching java.lang.Exception should be done with due consideration. Catching specific exceptions and handling the same should be the preferred route unless there are good cases for catching top level exceptions, which there are.

Anyway, my interest is not really with the above but more on the class java.lang.ThreadDeath. ThreadDeath is a sub-class of java.lang.Error. If one catches, java.lang.Throwable, then there is a possibility of also catching java.lang.ThreadDeath in that code.

The javadocs on ThreadDeath states:

"An instance of ThreadDeath is thrown in the victim thread when the stop method with zero arguments in class Thread is called.
An application should catch instances of this class only if it must clean up after being terminated asynchronously. If ThreadDeath is caught by a method, it is important that it be re thrown so that the thread actually dies.

The top-level error handler does not print out a message if ThreadDeath is never caught.

The class ThreadDeath is specifically a subclass of Error rather than Exception, even though it is a "normal occurrence", because many applications catch all occurrences of Exception and then discard the exception. "


So ThreadDeath can be noticed only if a call to thread.stop() has been made.
The stop() method in Java has been deprecated due to its usage being inherently unsafe.

As per the Java doc recommendation, code that might catch ThreadDeath should propagate the same higher up like shown below:

So for example:

try {
// Do some biz processing
....
} catch (Throwable t) {
if (t instanceof ThreadDeath)) {
throw ((ThreadDeath) t);
}

.......
.......
}

I remember my Architect (a very very smart man) during my earlier days when using jdk1.2.X, jdk1.3.X etc making sure of the above.

Now with stop() being deprecated can we safely assume that no code would ever call stop() on a Thread? I don't think we can be that optimistic as even though deprecated, it could still be invoked. So until the stop method is removed from the JDK, I believe it would be prudent to throw ThreadDeath when catching Throwable or Error specifically for the two reasons mentioned in the javadoc (contrary views I'd love to hear):

"If ThreadDeath is caught by a method, it is important that it be rethrown so that the thread actually dies.
The top-level error handler does not print out a message if ThreadDeath is never caught. "


I wonder if the practice of re-throwing ThreadDeath is still being followed :-) ?
Eric Williams book about the Threads is a nice read. Look for Thread Death in the example.

I cant wait to read Brian Goetz's Java Concurrency in practice, need to buy this book soon...:-). I love async code but it has been rather long since I have played (note the wicked word played :--)) with threads as last few years have all been spent faithfully following j2ee container thread usage recommendations.

No comments: