In Brian Goetz\'s article on how to handle InterruptedException, one paragraph stands out:
The one time it\'s acceptable to swallow an interrupt is wh
I agree with the others that the difference is whether you control that thread or not. If you extended a Thread, it's pretty much a given that you have control over that thread. On the other hand, if your code is simply a Runnable, it might be run on a borrowed thread (like from a thread pool) you do not own. By eating up the exception and not restoring the interrupt status, you deprive the code higher-up of the chance to recognize and act on the interruption.
InterruptedException being a checked exception is, I think, a good thing. An InterruptedException is a way to request a cancellation of tasks. Suppose one wrote a task in the form of a Runnable that involves a blocking method that throws an InterruptedException. If it were not a checked exception, if you're not being careful you may not think to act on the InterruptedException (thus cancellation) and do your own clean-up.
public class MyTask implements Runnable {
public void run() {
while (someCondition) {
Object value = someBlockingQueue.take();
// act on the value and loop back
}
}
}
Since InterruptedException is a checked exception, how my task should respond to interruption (cancellation) is front and center.
public class MyTask implements Runnable {
public void run() {
while (someCondition) {
try {
Object value = someBlockingQueue.take();
// act on the value and loop back
} catch (InterruptedException e) {
// I'm being cancelled; abort
cleanUp();
// restore the interrupt
Thread.currentThread().interrupt();
break;
}
}
}
}
I would argue that extending Thread
there was unnecessary, and therefore implementing Runnable
is preferred.
But the important thing is that the code knows the thread is going to exit. If your code is part of some generic callback interface then you can't know how you are being used. You could be passed to a thread pool (indeed, we probably should be using pools rather than constructing Thread
s at inappropriate points in the code). OTOH, usually the Runnable
is an anonymous inner class and therefore, at a source level, part of the enclosing method that does know what is going on.
So, if the thread is about to exit, resetting the interrupt state on the current thread is pointless because there is nothing to interrupt.
At some point you are going to want to say that it has interrupted enough. Thread pools for instance can continue to use a thread even after a task has been interrupted, although they might want to keep the InterruptException
around for the callers that attempt to pick up the task.
Libraries generally do not handle interrupts correctly. IMO, interrupts don't have the context to make sense. Life would be a lot simpler without them, unfortunately they make their presence felt.
Basically. The concern expressed in the article is that if you swallow the interupt exception then calling code higher in the stack won't know about the interuption, possibly causing undesirable behavior. If you start the thread, then you know there is nothing higher in the call stack that cares about being interupted, this thread will not continue to live in a thread pool, so just let the thread die.
I hate InterruptedException, I think it gives checked exceptions a bad name, and this article doesn't change that perspective. If it was so important that this exception pass up the call stack, Runnable.run() should have it declared in the method declaration so you can simply rethrow it, or it should have been an unchecked exception for the same reason SecurityException is an unchecked exception.
My prefered design would be that the methods return a boolean if they were interrupted if you care to know, but this article does make the case that that wouldn't necessarily be practical.