I’m trying to understand how threads work in Java and currently investigating how to implement looped threads that can be cancelled. Here’s the code:
public static void main(String[] args) throws Exception { Thread t = new Thread() { @Override public void run() { System.out.println("THREAD: started"); try { while(!isInterrupted()) { System.out.printf("THREAD: working...n"); Thread.sleep(100); } } catch(InterruptedException e) { // we're interrupted on Thread.sleep(), ok // EDIT interrupt(); } finally { // we've either finished normally // or got an InterruptedException on call to Thread.sleep() // or finished because of isInterrupted() flag // clean-up and we're done System.out.println("THREAD: done"); } } }; t.start(); Thread.sleep(500); System.out.println("CALLER: asking to stop"); t.interrupt(); t.join(); System.out.println("CALLER: thread finished"); }
The thread I create is indended to be interrupted sooner or later. So, I check isInterrupted() flag to decide whether I need to go on and also catch InterruptedException
to handle cases when I’m in a kind of waiting operation (sleep
, join
, wait
).
Things I’d like to clarify are:
- Is it fine to use interruption mechanism for this kind of task? (comparing to having
volatile boolean shouldStop
) - Is this solution correct?
- Is it normal that I swallow InterruptedException? I’m not really interested what was the piece of code where someone asked my thread to interrupt.
- Are there any shorter ways to solve this problem? (the main point is having ‘infinite’ loop)
EDIT
Added call to interrupt()
in catch for InterruptedException
.
Advertisement
Answer
I am answering no. 3:
Basically the question is: What purpose does an Interrupted exception have? It tells you to stop blocking (e.g. sleeping) and return early.
There are two ways dealing with an InterruptedException:
- Rethrow it, so the thread remains interrupted
- set
Thread.currentThread.interrupt()
again and do your cleanup work. This way you can be sure that another method in your thread starting to sleep will throw again
Simply swallowing an InterruptedException
is not a good idea regarding the purpose of such an interrupt which is to finally terminate. But you are only asked to interrupt so you still have time to clean up.
In this case this might be an ‘overreaction’ of myself, but typically such code is much more complicated and how do you know, that some follow-up-code in this Thread would not call a blocking method again?
EDIT
Otherwise I think what you’re doing is fine. For me a bit surprising, though, because I never saw anyone in his own code actually doing it.
And interesting article explaining why can be found here: http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html