Alojzij Blatnik
Alojzij Blatnik

Reputation: 111

Handling InterruptedException in main thread

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

Answers (1)

Nathan Hughes
Nathan Hughes

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

Related Questions