Saturday, June 14, 2014

Thread Interruption in Java

This week a question came up at work about the best way to handle an InterruptedException thrown from Thread.sleep(...). Often times, developers will simply catch this exception, and then just print a stack trace, or leave the block completely empty. However, this is not good practice, since you are essentially ignoring the fact that your app has been interrupted:

For example, say you have a thread which processes a given number of records, with a configurable sleep in between each record to allow you to throttle the speed. If not handled properly, the thread will never exit gracefully. For example:

Note that simply calling Thread.currentThread.interrupt() will not kill the running thread. In this case, the thread will continue to run, interrupting itself over and over again. A better way to handle the InterruptedException is to gracefully discontinue processing records, for example:

In this example, the private sleep method properly throws the InterruptedException up the stack to a piece of code which knows how to handle it properly.

To run an example of the non-interruptable runnable and the interruptable runnable, you can clone the project from GitHub Here.

2 comments:

  1. Nice post!
    Also may I add: in a thread, if not performing a blocking operation (sleep(), wait(), etc.), it needs to explicitly check the interrupted flag in order to make use of it. Say if a thread is interrupted in InterruptableRunnable.run(), its interrupted flag will be set to true, but if that thread does not call Thread.currentThread().isInterrupted() to check its flag and react accordingly, Thread.currentThread().interrupt() will have no effects on it.

    ReplyDelete
    Replies
    1. Thanks Alan. If you run the example code from the GitHub project, you can see this in action when the NonInterruptableRunnable runs. Since it calls interrupt, followed by a blocking operation (sleep), it continues to interrupt itself, while still processing each record (which is bad). Checking the isInterrupted() flag would be another way of making sure that his thread does not block after it has been interrupted. Thanks!

      Delete