Code Pumpkin

InterruptedException in Java Multithreading

Subscribe

InterruptedException is thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity.

Before reading this article, I recommend you to go through my article interrupt(), interrupted() and isInterrupted() in Java Multithreading.

There are some methods in JDK that check the Interrupt status flag for us and throw InterruptedException, if it is set.  For example, All the blocking methods i.e. wait(), sleep()join()

I have not seen many programmers handle InterruptedException correctly. Most of the time, programmers view them as an irritating checked exceptions that they have to catch.  

Just to ignore IDE's compilation error angry, they wrap sleep() or wait() method call with try-catch block having InterruptedException.  crying

The Question arises here is, why all blocking method throws InterruptedException? Let's understand this by following example. Here is the implementation of my thread's run() method.



@Override
public void run() 
{
	while (true) 
	{
		if (Thread.interrupted()) 
		{
			break;
		}
		
		// Case 1 : code to be executed before sleep method call
		
		try
		{
			sleep(10_000_000); // Case 2 : sleep for 10,000 seconds
		}
		catch(InterruptedException ie)
		{
			// Clean up code
		}
		
		// Case 3 : code to be executed after sleep method call
	}
	
	// Clean up code
}

In above code, my run() method checks for Thread.interrupted() in the starting of each loop iteration.  If Interrupt status flag is true, it will break the while loop. else it will complete that iteration.

I have also highlighted three execution points. Let's understand what will happen when parent thread call interrupt() method and execution has reached to any one of these three execution points. 


case 3 : 

  1. Cursor has reached to line 22 and its executing code after the sleep() method.
  2. At the same time, main thread calls  interrupt() method.
  3. Cursor will complete that iteration and will start next iteration.
  4. Cursor will enter if block as Thread.interrupted() will return  true. It will break the while loop.
  5. Cursor will execute clean up code written on line 25.

case 2 :

  1. Cursor has reached to line 15 and its executing code of native sleep() method.
  2. At the same time, main thread calls  interrupt() method.
  3. sleep() method throws InterruptedException. Imagine if there is no mechanism like InterruptedException . Even though your parent thread has called interrupt method, child thread can't be stopped as it will sleep for 10,000 seconds (around 3 hours). To overcome such situations sleep() method internally keeps checking for Interrupt status flag.
  • This is how the method Thread.sleep() may have designed internally in java.
  • 
    
    public static void sleep(long millis) throws InterruptedException 
    {
        while (/* still waiting for millis to become zero */) 
        {
            if (Thread.interrupted())
            {
                throw new InterruptedException();
            }
            // Keep waiting
        }
    }
    

     Note : Thread.sleep()is a native method of Thread class. Above code snippet is just to show high level implementation overview of it.

  1. Cursor will move to catch block and execute clean up code written on line 19.

case 1 :

  1. Cursor has reached to line 11 and its executing code before the sleep() method.
  2. At the same time, main thread calls  interrupt() method.
  3. Cursor will complete executing code before thesleep() method and enters sleep() method.
  4. sleep() method throws InterruptedException.
  5. Cursor will move to catch ​block and execute clean up code written on line 19.

Real Time Usage of InterruptedException

Main reason for throwing InterruptedException is to unblock (for some reason) a thread  that is blocked and execute cleanup code. We can take an example of application shutdown.

When you shutdown your application, if you have threads waiting on let say sleep() or wait() , if you do not tell them that you are shutting down they will continue to wait(). If those threads are not daemon threads, then your application won't shutdown.

So, when thread gets interrupted during sleep(), you have to check the conditions and handle the situation. In case of shutdown, you have to check your shutdown flag and eventually do the clean-up work and let the thread go.


What will happen if developer swallows the InterruptedException and do nothing inside catch block?



try {
  Thread.sleep(100);
} catch (InterruptedException ex) {
}

Remember, Thread.interrupted() not only returns the flag but also sets it to false. Thus, once InterruptedException is thrown, the flag is reset. The parent thread no longer knows anything about the interruption request sent by the owner.

The owner of the thread asked us to stop, Thread.sleep() detected that request, removed it, and threw InterruptedException. If you call Thread.sleep(), again, it will not know anything about that interruption request and will not throw anything.

It's very important not to lose that InterruptedException. We can't just swallow it and move on. That would be a severe violation of the entire Java multi-threading idea. Our owner (the owner of our thread) is asking us to stop, and we just ignore it. That's a very bad idea.

This is what most of us are doing with InterruptedException:



try {
  Thread.sleep(100);
} catch (InterruptedException ex) {
  throw new RuntimeException(ex);
}

It looks logical, but it doesn't guarantee that the higher level will actually stop everything and exit. They may just catch a runtime exception there, and the thread will remain alive. The owner of the thread will be disappointed.

We have to inform the higher level that we just caught an interruption request. We can't just throw a runtime exception. Such behavior would be too irresponsible. The entire thread received an interruption request, and we merely swallow it and convert it into a RuntimeException. We can't treat such a serious situation so loosely.

This is what we have to do:



try {
  Thread.sleep(100);
} catch (InterruptedException ex) {
  Thread.currentThread().interrupt(); // Here!
  throw new RuntimeException(ex);
}

We're setting the flag back to true!

Now, nobody will blame us for having an irresponsible attitude toward a valuable flag. We found it in true status, cleared it, set it back to true, and threw a runtime exception. What happens next, we don't care.

That's all about InterruptedException. Don't just swallow them. wink

Happy Learning smiley

Tags: , , , ,


Comments and Queries

If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code class="java"> 
String foo = "bar";
</code></pre>
For more information on supported HTML tags in disqus comment, click here.

Total Post : 80
Subscribe
Contribute Your Articles

Interview Experiences

Related Books

Like Us On Facebook

Alexa Page Rank