InterruptedException in Java Multithreading
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 , they wrap sleep()
or wait()
method call with try-catch
block having InterruptedException
.
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 :
-
Cursor has reached to line 22 and its executing code after the
sleep()
method. -
At the same time, main thread calls
interrupt()
method. - Cursor will complete that iteration and will start next iteration.
-
Cursor will enter if block as
Thread.interrupted()
will return true. It will break the while loop. - Cursor will execute clean up code written on line 25.
case 2 :
-
Cursor has reached to line 15 and its executing code of native
sleep()
method. -
At the same time, main thread calls
interrupt()
method. -
sleep()
method throwsInterruptedException
. Imagine if there is no mechanism likeInterruptedException
. 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 situationssleep()
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.
-
Cursor will move to
catch
block and execute clean up code written on line 19.
case 1 :
-
Cursor has reached to line 11 and its executing code before the
sleep()
method. -
At the same time, main thread calls
interrupt()
method. -
Cursor will complete executing code before the
sleep
()
method and enterssleep()
method. -
sleep()
method throwsInterruptedException
. -
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.
That's all for this topic. If you guys have any suggestions or queries, feel free to drop a comment. We would be happy to add that in our post. You can also contribute your articles by creating contributor account here.
Happy Learning 🙂
If you like the content on CodePumpkin and if you wish to do something for the community and the planet Earth, you can donate to our campaign for planting more trees at CodePumpkin Cauvery Calling Campaign.
We may not get time to plant a tree, but we can definitely donate ₹42 per Tree.
About the Author
Tags: Concurrency, Core Java, Java, Multithreading, Thread
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.