1) why Java is designed in such way that InterruptedException is being thrown only in case of blocking methods like sleep() and wait().
The whole point of thread.interrupt()
is that it is cooperative. A thread is interrupted but it has to check for the interrupt flag using Thread.currentThread().isInterrupted()
so it can manage it's own termination properly and clean up the shared objects, locks, finally blocks, etc. if necessary.
To quote from the tutorial on the subject, emphasis mine.
An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate.
The methods that do throw InterruptedException
are the ones that are waiting on locks and other conditions. These throw the exception when they are interrupted so again the thread can clean itself up before terminating.
2) Why in normal code, we need to handle this manually as in my above code snippet? Why Java is not throwing InterruptedException whenever we set interrupted flag true through interrupt() method?
The alternative would have been to have InterruptedException
be a RuntimeException
which could have been thrown at any time regardless of whether or not the program was anticipating it. Part of the problem with stop()
and the other deprecated Thread
methods was that they tended to violate various language constructs and could possibly leave the
application memory in a bad state. Here's more details about that.
The same could be said for InterruptedException
if it was a RuntimeException
. You can imagine if a thread was altering a shared object and then just midstream threw a unexpected RuntimeException
or was stopped altogether. The shared object being updated could easily be left in a invalid state.
if (Thread.interrupted()) {
This is not the right method to call because it clears the interrupt flag on the thread which is a bad pattern. Please use the following:
if (Thread.currentThread().isInterrupted()) {
This preserves the interrupt flag which should be done if possible. Also, when InterruptedException
is thrown that also clears the interrupt flag. That's why it's a good pattern to do:
try {
...
} catch (InterruptedException ie) {
// re-interrupt the thread to propagate the interrupt flag
Thread.currentThread().interrupt();
// handle the interrupt here by probably quitting the thread
}
There are many problems where libraries "swallow" the interrupt flag. Even if your code is small it may get copied into a larger block so you always way to restore the interrupt flag as a good pattern.