Design: Would it not make more sense to construct a Thread with something that can throw an InterruptedException?

95 Views Asked by At

I'm wondering what might have been the reason Java Thread's doesn't accept a Runnable that allows throwing of InterruptedException. If instead an InterruptableRunnable was accepted, it would simplify a lot of code that will simply want to stop the thread when interrupted.

interface InterruptableRunnable {
    void run() throws InterruptedException;
}

Before:

new Thread(() -> {
    try {
        Thread.sleep(1000);
    }
    catch (InterruptedException e) {
        // Some confusion ensues here as to what to do;
        // - Should we restore the interrupt? For who? Guess not.
        // - Should we rethrow it? That would terminate thread exceptionally...
        // - Just return then? Sounds good...
        
        return;
    }
}).start();

Now, if instead you could use an InterruptableRunnable the code would be far simpler, and I think just as correct:

new Thread(() -> {
    Thread.sleep(1000);
}).start();

On an interrupt, the thread gets terminated exactly as you'd expect -- and the system could be smart enough not to consider an InterruptedException as an exceptional termination condition. If that's not what you want, you always have the option of catching the exception.

For similar reasons, what could have been the reasoning Thread#run() is not declared to throw InterruptedException...

1

There are 1 best solutions below

4
Nathan Hughes On

Exceptions don't propagate across threads, for instance you need an UncaughtExceptionHandler to retrieve the exception thrown by another thread, see How to catch an Exception from a thread.

So putting InterruptedException in the throws clause creates a false expectation, the exception still can't be thrown in one thread and caught in another. That's the only reason I can think of for not doing this, they are trying to communicate to the developer that the toplevel run method for a thread needs to handle everything. Putting InterruptedException in the throws clause dilutes this message, as the developer isn't forced to deal with it.

But yes, they could have added InterruptedException to the throws clause of Runnable, that would make this case much simpler. But there are design goals in conflict. The designars want developers to be very aware of the exception behavior, including making InterruptedException checked, but it's not having it in the throws clause that forces people to deal with it. The goal of letting simple things be easy and having a thread call sleep without a catch is at odds with that so it wasn't implemented.