Reputation: 111
I'm wondering what's the correct way of handling InterruptedException
in main
thread. When the main
thread gets interrupted?
I see that join()
method throws InterruptedException
, but I'm wondering how can I clean up the secondary thread to terminate gracefully.
Here's the sample program:
public class Main {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
while (true) {
if (Thread.interrupted()) {
break;
}
}
System.out.println("[thread] exiting...");
}
};
System.out.println("[main] starting the thread");
t.start();
System.out.println("[main] interrupting the secondary thread");
t.interrupt();
try {
t.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
System.out.println("[main] exiting");
}
}
This code will print the following output:
[main] starting the thread
[main] interrupting the secondary thread
[thread] exiting...
[main] exiting
I found that certain articles on the internet (such as this http://www.yegor256.com/2015/10/20/interrupted-exception.html) suggest to set interrupt
flag to true and to throw RuntimeException
. I don't see how this would mitigate the situation (cleaning the remaining threads before exiting).
Thanks.
Edit: code snipped I referred in a comment
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread mainThread = Thread.currentThread();
Thread t = new Thread() {
public void run() {
while (true) {
if (Thread.currentThread().isInterrupted()) {
break;
}
}
System.out.println("[thread] interrupting the main thread...");
mainThread.interrupt();
System.out.println("[thread] exiting...");
}
};
System.out.println("[main] starting the thread");
t.start();
System.out.println("[main] interrupting the secondary thread");
t.interrupt();
try {
t.join();
} catch (InterruptedException e) {
System.out.println("[main] InterruptedException indeed happened");
Thread.currentThread().interrupt();
throw e;
}
System.out.println("[main] exiting");
}
}
Upvotes: 2
Views: 2397
Reputation: 96444
In your example nothing is going to interrupt the main thread, none of the code handling the InterruptedException
thrown from the call joining on the secondary thread will get executed. So it really doesn't matter. The point of setting the interrupt flag is to let other things executing in that thread know of the interruption so everything can quit what it's doing, that is not a concern here.
You could wrap the main method in a try-catch
block that logs anything it catches. That's a normal thing to do to make sure all exceptions get logged.
Your code invokes interrupt
on the secondary thread. As long as that thread is written to respond to interruption by cleaning up and quitting then there isn't any more to do.
Don't use Thread.interrupted()
, use Thread.currentThread().isInterrupted()
. The interrupted
method clears the interrupt flag as a side effect.
Catching the InterruptedException
and throwing a RuntimeException
is not consistent with how the java.util.concurrent
classes are written. It's more idiomatic to let the InterruptedException
be thrown than to wrap it in an unchecked exception.
The example code can't be interrupted by signals, you would have to implement that functionality yourself by writing your own signal handler.
Upvotes: 3