Assume that I have the following code:
while(!Thread.currentThread().isInterrupted()){
//do something
Thread.sleep(5000);
}
Now Thread.sleep
throws `InterruptedException so it should be like this:
while(!Thread.currentThread().isInterrupted()){
//do something
try{
Thread.sleep(5000);
} catch(InterruptedException e){
}
}
If I hit the catch
will the while
loop continue or do I need to do Thread.currentThread().interrupt()
? If I do call this method, won't that also cause an InterruptedException
? Otherwise how I got the exception in the first place?
Also if I have:
while (!Thread.currentThread().isInterrupted()){
//do something
callMethod();
}
private void callMethod(){
//do something
try {
Thread.sleep(5000);
} catch(InterruptedException e){
}
}
again will my while
loop break?
Actually your question is more about try - catch - finally
than about multithreading.
1) If sleep
throws an Exception
, the catch
block will execute and then the while
loop continues.
2) You do the exact same thing as in 1)
To leave the while
loop, do:
try{
while(!Thread.currentThread.isInterrupted){
//do something
Thread.sleep(5000);
}
}
catch(InterruptedException e){
}
In that case, if an Exception
is thrown, the while
loop is left and the catch
block is executed.
Thread.sleep()
will clear the "interrupted status" before throwing InterruptedException
. You need to call Thread.currentThread().interrupt()
in the catch block, otherwise the while condition will most likely not succeed, because the thread will always be "not interrupted" when callMethod
returns.
The exception is not caused by the interrupt()
method, but by sleep()
blocking on a thread that has been signaled as "interrupted". This is explained in more detail here. See also this answer.
Calling interrupt on a thread does not in itself throw an exception. Sleeping or waiting while the interrupt flag is set is what causes InterruptedException to be thrown.
It is totally predictable what can throw InterruptedException, so that the thread being interrupted has control and it can choose how to respond. It's a checked exception so it's evident what throws it. It is not like ThreadDeath, which can be thrown anywhere.
When an InterruptedException is thrown the thread's interrupted status is reset. If you want to restore the thread's interrupted status, because you want to check the flag later and have it be true, call Thread.currentThread().interrupt()
in order to set it.
Nothing out of the ordinary happens during interruption to change how instructions get processed. So if you choose to catch the InterruptedException in a loop and check the flag to get out, you will need to reset the flag:
while(!Thread.currentThread().isInterrupted()){
//do something
try{
Thread.sleep(5000);
} catch(InterruptedException e){
Thread.currentThread().interrupt();
}
}
Alternatively you can use the InterruptedException to get out of the loop:
try {
while (!Thread.currentThread().isInterrupted()) {
// do something
Thread.sleep(5000);
}
} catch (InterruptedException e) {
// flag value is not used here, but still good style
Thread.currentThread().interrupt();
}
If this last snippet is the whole run method of the thread being interrupted, you can get by without setting the interrupted status again, but if you have components being used by other parts you don't want one badly-behaved part to squelch the interrupted flag so that other code in the thread is not aware of the interruption.