Is it OK to ignore InterruptedException if nobody calls interrupt()?

17,729

Solution 1

Ignoring a checked exception is never considered to be safe.
It may be ok for you at the moment, but if another programmer extends your code, he will expect the standard behaviour: the thread reacting to an interrupt call.
Also an empty catch block is dangerous in this case, since the JVM removes the interrupted flag and it should definitely be set again with

Thread.currentThread().interrupt();

in the catch block. In my opinion, this is the minimum catch implementation for InterruptedExceptions. Checking for the isInterrupted flag in a loop doesn't hurt much, either.
It is little overhead compared to your future programmer self's hassle searching a day or two for unexpected thread behaviour as you project may have grown a bit.

If you feel that your code's readability suffers from those catch implementations, you may implement your own safeSleep utility method, which takes care of the Exceptions and sets the flag properly.

On the other hand, InterruptedException is not thrown by the JVM itself in case of a hardware failure, it is a user indicated Exception only. So, if you do not propagate your Threads reference, there won't be any other Threads that are able to call Thread.interrupt() on it. That's it technically. But you shouldn't underestimate the human factor and your programs evolution.
Edit: As ruakh pointed out, there actually is a way to get a Threads reference and thus to schedule an Thread.interrupt() call. That way the developer in heat may not even have to look at the class, that implements your uninterruptible Thread. In my opinion that's even another reason, to implement proper exception handling.
Another thing: If you're not throwing an Exception, logging such an event on a level beyond INFO may be a good choice.

Solution 2

Instead of swallowing it, if you're so sure it will never happen, you can crash instead of ignoring it. For example, throw an Error (or a RuntimeException):

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    throw new Error(e);
}

From the Javadocs for Error:

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.

If you think it's worth assuming something will never happen, then if it does happen, that's an "abnormal condition" that, who knows, might just be a "serious problem".

Another way to look at this is, if someone in the future does interrupt your method, is there any chance that they will want it to continue running as if nothing had happened? I would guess no.

Solution 3

You should never swallow an exception if you think that it should never occur. It’s ok to decide not to add code handling a condition which never occurs but it shouldn’t happen silently.

The minimum you should do is:

catch(InterruptedException ex) {
  throw new AssertionError(ex);
}

This ensures that whenever your assertion that this will never occur is wrong, you will notice. This pattern also applies to other unexpected exceptions, e.g. IOException when you know that the target OutputStream is a ByteArrayOutputStream or the Appendable of a Formatter ought to be a StringBuilder, etc.


By the way, there is an alternative to Thread.sleep not requiring to deal with InterruptedException at all:

LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(timeInMillis));

This method will simply return earlier when the thread has been interrupted and retain the interrupted state of the Thread so it provides already a correct handling for the case that your code is used by someone else who does use interruption (assuming that the caller of your code checks the interrupted state then).

Solution 4

The book that I still consider the bible on these matters, Goetz et al. Java Concurrency in Practice says the following important bits in chapter 7 (Pretty much the same material is found in Goetz's developerWorks article, which has the advantage of being free, but the book is a bit more clear on some points.)

Interruption is a cooperative mechanism. One thread cannot force another to stop what it is doing and do something else; when thread A interrupts thread B, A is merely requesting that B stop what it is doing when it gets to a convenient stopping point—if it feels like it.

[...]

Only code that implements a thread’s interruption policy may swallow an interruption request. General-purpose task and library code should never swallow interruption requests.

So, yes, you can "swallow" InterruptedException under the circumstances you outlined.

Also an important point in the book:

Because each thread has its own interruption policy, you should not interrupt a thread unless you know what interruption means to that thread.

So you can choose your own policy like "crashing" with a RuntimeException, AssertionError, just logging it as a warning, or ignoring interruption altogether as long as you document this issue for whoever else might need to know. What is best depends on what your thread is really doing and you haven't provided any details on that. For example, if it's running on a rocket [say doing attitude control], you do not want to crash the JVM/rocket just because a fellow programmer [who might not even work for the same company as you, e.g. he wrote some library you call] forgot about a certain contract somewhere in his code and dumps a safely ignorable exception on yours: "The exception which occurred was not due to random failure but a design error."

Solution 5

It should not be ignored. It should either be thrown back to the caller or you should reassert the thread's interrupted status which is cleared when the exception is thrown:

catch (InterruptedException e) { 
     // Restore the interrupted status
     Thread.currentThread().interrupt();
 }

unless you prompty exit the thread after the catch.

Here's an article about dealing with InterruptedExceptions.

Share:
17,729
Hilikus
Author by

Hilikus

"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." - M. Fowler

Updated on June 17, 2022

Comments

  • Hilikus
    Hilikus almost 2 years

    If I create my own thread (i.e. not a threadpool) and somewhere I call sleep or any other interruptible method, is it ok to ignore the InterruptedException if I know nobody else in the code is doing an interrupt on the thread.

    In other words, if the thread is supposed to live as long as the JVM, meaning the thread is not interruptible, is it safe to assume that InterruptedException will never be called and therefore the exception can be swallowed?

  • kapex
    kapex about 9 years
    If you just re-throw the exception, wouldn't that have the same effect as killing the thread with the deprecated Thread.stop() method? Who will catch the exception?
  • Solomon Slow
    Solomon Slow about 9 years
    What is "the standard behavior?" clean up and shut down?
  • Solomon Slow
    Solomon Slow about 9 years
    Also, if you have reason to believe that your code can safely ignore some exception, then you should at least call LOGGER.debug(ex), so that it will be easier to figure out what happened if your belief should somehow turn out to be wrong.
  • Zhedar
    Zhedar about 9 years
    @james large in fact, there may be no standard behaviour, but an expected one. that is aborting the current process and finishing gracefully. but as always: documentation is key here.
  • user253751
    user253751 about 9 years
    I normally use AssertionError for this, but that's mostly just a personal preference.
  • Hilikus
    Hilikus about 9 years
    @jameslarge for me, just printing a log message is still ignoring the exception
  • sfdcfox
    sfdcfox about 9 years
    And, later, when it crashes six months down the line, because you write something that needs to interrupt it, you'll remember why you decided not to silently swallow the error to begin with. Or, you'll have a subtle bug, like data not getting saved to a database, memory leaks, or whatever other resources this thread might be holding.
  • Solomon Slow
    Solomon Slow about 9 years
    @Hilikus, I agree. Holger's answer explained why its a bad idea to ignore an exception that you think can never happen. I tacked on my comment to say something about the rare case where you know the exception will happen, and you mean to ignore it.
  • Dorus
    Dorus about 9 years
    UGH. This is ugly, if you are going to rethrow the InterruptedException, just throw the InterruptedException itself. This is especially true for library code. If this is your application code, it really wont make any difference if you rethrown or ignore the exception anyway, since you can guarantee it's not caused in the first place. The other option is to gracefully exit your thread.
  • Dan Getz
    Dan Getz about 9 years
    @Dorus the question was for code written inside a thread. You can't throw an InterruptedException from Runnable.run() unless it's wrapped inside something else. If you mean, "throw the InterruptedException inside some method that you then call", sure, but then what do you do in the thread that calls it?
  • Dorus
    Dorus about 9 years
    Mmm true, once you reach thread level, crashing or gracefully ending your thread are both valid options. Got to agree. Pick what fits best.
  • Admin
    Admin about 9 years
    +int(PI/3) for LockSupport - you made me learn yet another not-so-common feature of Java today...
  • ruakh
    ruakh about 9 years
    Re: "if you do not propagate your Threads reference there won't be any other Threads, that are able to call Thread.interrupt() on it": Threads aren't like random objects, that you can decide whether or not to propagate. The JDK offer methods for finding all threads. See stackoverflow.com/questions/1323408/… for a few approaches.
  • Zhedar
    Zhedar about 9 years
    @ruakh Thanks for your comment. I've corrected this in my answer.
  • randers
    randers about 8 years
    Regarding the safeSleep method: Instead of implementing your own, you can also use Guava's Uninterruptibles (e.g. Uninterruptibles.sleepUninterruptibly)
  • Ranger
    Ranger almost 7 years
    "On the other hand, InterruptedException is not thrown by the JVM itself": can you support this claim by linking to documentation/specification stating this?
  • Zhedar
    Zhedar almost 7 years
    @EduardWirch I think i got it from a German book by Michael Inden, which I do not have at hand right now. But a quick search brought up this SO-answer, which references the JLS section 17.2.3: Interruption actions occur upon invocation of Thread.interrupt, as well as methods defined to invoke it in turn, such as ThreadGroup.interrupt.