What is an InterruptedException in Java? - java

I have seen many times in my code that I get an Interrupted Exception. How do I fix it?
Example:
for (int i = 0; i < readLimit; i++) {
if (fileName.exists())
return readFile(fileName);
Thread.sleep(1000); // Here is where I get the error
}
}

Since I don't know how much you know about Java, how java works exactly and what's concurrency, I'll try to explain as much as possible with nearly no background information needed.
At first we're going to take a look at Oracle's documentation of the InterruptedException.
Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity. [...]
What does this mean?
Before answering this question you have to rudimentary understand how a Thread works.
A thread is originally just a piece of code that can be managed seperately from other threads. It can run at the same time (see concurrency), run scheduled, etc.
Example
If you start a normal java program the main() method is created in an own thread 1. Everything you do will be executed in this thread. Every class you create, every method you call and basically everything that originated from main().
But if you create a Thread, it runs in an own thread 2. Everything you do in the run() method will be executed in thread 2.
What happens if you create a new Thread?
The join() method is called.
The join() method starts the thread and run() is being executed.
There's not only the join() method with no parameters but also a join(long millis) with a parameter.
When and why is it thrown?
As Rahul Iyer already said there's a variety of reasons. I'm picking some of them to get you a feeling when they're called.
Timeout
The InterruptedException can be indeed thrown when a timeout was exceeded. This happens when the join(long millis) is called. The parameter specifies that the thread can run for the given amount of milliseconds. When the thread exceeds this timeout it is interrupted. source (from line 769 to line 822).
OS is stopping the thread
Maybe the Operating System (Windows, Linux, Android, etc.) decided to stop the program. Why? To free resources, your program was mistaken as a virus, hardware is shutting down, the user manually closed it, etc.
An InterruptedException is thrown in the Thread
For example you're connected to the internet and you're reading something and the internet disconnects suddenly.
interrupt() is called
As already mentioned, an InterruptedException is also thrown, when you call the interrupt() on any Thread (quite logical).
How to handle it?
You can/should handle it like every other exception. Wrap it in a try and catch, declare that the method throws it, log it, etc.
This may be the best resource for you: Handling InterruptedException in Java.

From the docs: https://docs.oracle.com/javase/7/docs/api/java/lang/InterruptedException.html
public class InterruptedException extends Exception
Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is
interrupted, either before or during the activity. Occasionally a
method may wish to test whether the current thread has been
interrupted, and if so, to immediately throw this exception. The
following code can be used to achieve this effect:
if (Thread.interrupted()) // Clears interrupted status!
throw new InterruptedException();
You can follow oracles tutorial here:
https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
The way to fix it is probably to surround the code that causes it with a Try-Catch block and handle the exception. For example (from Oracles tutorial):
for (int i = 0; i < importantInfo.length; i++) {
// Pause for 4 seconds
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
// Print a message
System.out.println(importantInfo[i]);
}
There are more examples in the above link on how to handle different scenarios.

Shortly, InterruptedException is usually thrown when a thread or some other action is interrupted. It does not matter if the thread was doing something or sleeping, you can programmatically do this by calling interrupt() or other methods on and "occupied" thread, who is for sleeping.

Related

Interrupted Exception Error in Java for Exception [duplicate]

What is the difference between the following ways of handling InterruptedException? What is the best way to do it?
try{
//...
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
}
OR
try{
//...
} catch(InterruptedException e) {
throw new RuntimeException(e);
}
EDIT: I'd like to also know in which scenarios are these two used.
What is the difference between the following ways of handling InterruptedException? What is the best way to do it?
You've probably come to ask this question because you've called a method that throws InterruptedException.
First of all, you should see throws InterruptedException for what it is: A part of the method signature and a possible outcome of calling the method you're calling. So start by embracing the fact that an InterruptedException is a perfectly valid result of the method call.
Now, if the method you're calling throws such exception, what should your method do? You can figure out the answer by thinking about the following:
Does it make sense for the method you are implementing to throw an InterruptedException? Put differently, is an InterruptedException a sensible outcome when calling your method?
If yes, then throws InterruptedException should be part of your method signature, and you should let the exception propagate (i.e. don't catch it at all).
Example: Your method waits for a value from the network to finish the computation and return a result. If the blocking network call throws an InterruptedException your method can not finish computation in a normal way. You let the InterruptedException propagate.
int computeSum(Server server) throws InterruptedException {
// Any InterruptedException thrown below is propagated
int a = server.getValueA();
int b = server.getValueB();
return a + b;
}
If no, then you should not declare your method with throws InterruptedException and you should (must!) catch the exception. Now two things are important to keep in mind in this situation:
Someone interrupted your thread. That someone is probably eager to cancel the operation, terminate the program gracefully, or whatever. You should be polite to that someone and return from your method without further ado.
Even though your method can manage to produce a sensible return value in case of an InterruptedException the fact that the thread has been interrupted may still be of importance. In particular, the code that calls your method may be interested in whether an interruption occurred during execution of your method. You should therefore log the fact an interruption took place by setting the interrupted flag: Thread.currentThread().interrupt()
Example: The user has asked to print a sum of two values. Printing "Failed to compute sum" is acceptable if the sum can't be computed (and much better than letting the program crash with a stack trace due to an InterruptedException). In other words, it does not make sense to declare this method with throws InterruptedException.
void printSum(Server server) {
try {
int sum = computeSum(server);
System.out.println("Sum: " + sum);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // set interrupt flag
System.out.println("Failed to compute sum");
}
}
By now it should be clear that just doing throw new RuntimeException(e) is a bad idea. It isn't very polite to the caller. You could invent a new runtime exception but the root cause (someone wants the thread to stop execution) might get lost.
Other examples:
Implementing Runnable: As you may have discovered, the signature of Runnable.run does not allow for rethrowing InterruptedExceptions. Well, you signed up on implementing Runnable, which means that you signed up to deal with possible InterruptedExceptions. Either choose a different interface, such as Callable, or follow the second approach above.
Calling Thread.sleep: You're attempting to read a file and the spec says you should try 10 times with 1 second in between. You call Thread.sleep(1000). So, you need to deal with InterruptedException. For a method such as tryToReadFile it makes perfect sense to say, "If I'm interrupted, I can't complete my action of trying to read the file". In other words, it makes perfect sense for the method to throw InterruptedExceptions.
String tryToReadFile(File f) throws InterruptedException {
for (int i = 0; i < 10; i++) {
if (f.exists())
return readFile(f);
Thread.sleep(1000);
}
return null;
}
This post has been rewritten as an article here.
As it happens I was just reading about this this morning on my way to work in Java Concurrency In Practice by Brian Goetz. Basically he says you should do one of three things
Propagate the InterruptedException - Declare your method to throw the checked InterruptedException so that your caller has to deal with it.
Restore the Interrupt - Sometimes you cannot throw InterruptedException. In these cases you should catch the InterruptedException and restore the interrupt status by calling the interrupt() method on the currentThread so the code higher up the call stack can see that an interrupt was issued, and quickly return from the method. Note: this is only applicable when your method has "try" or "best effort" semantics, i. e. nothing critical would happen if the method doesn't accomplish its goal. For example, log() or sendMetric() may be such method, or boolean tryTransferMoney(), but not void transferMoney(). See here for more details.
Ignore the interruption within method, but restore the status upon exit - e. g. via Guava's Uninterruptibles. Uninterruptibles take over the boilerplate code like in the Noncancelable Task example in JCIP § 7.1.3.
What are you trying to do?
The InterruptedException is thrown when a thread is waiting or sleeping and another thread interrupts it using the interrupt method in class Thread. So if you catch this exception, it means that the thread has been interrupted. Usually there is no point in calling Thread.currentThread().interrupt(); again, unless you want to check the "interrupted" status of the thread from somewhere else.
Regarding your other option of throwing a RuntimeException, it does not seem a very wise thing to do (who will catch this? how will it be handled?) but it is difficult to tell more without additional information.
The correct default choice is add InterruptedException to your throws list. An Interrupt indicates that another thread wishes your thread to end. The reason for this request is not made evident and is entirely contextual, so if you don't have any additional knowledge you should assume it's just a friendly shutdown, and anything that avoids that shutdown is a non-friendly response.
Java will not randomly throw InterruptedException's, all advice will not affect your application but I have run into a case where developer's following the "swallow" strategy became very inconvenient. A team had developed a large set of tests and used Thread.Sleep a lot. Now we started to run the tests in our CI server, and sometimes due to defects in the code would get stuck into permanent waits. To make the situation worse, when attempting to cancel the CI job it never closed because the Thread.Interrupt that was intended to abort the test did not abort the job. We had to login to the box and manually kill the processes.
So long story short, if you simply throw the InterruptedException you are matching the default intent that your thread should end. If you can't add InterruptedException to your throw list, I'd wrap it in a RuntimeException.
There is a very rational argument to be made that InterruptedException should be a RuntimeException itself, since that would encourage a better "default" handling. It's not a RuntimeException only because the designers stuck to a categorical rule that a RuntimeException should represent an error in your code. Since an InterruptedException does not arise directly from an error in your code, it's not. But the reality is that often an InterruptedException arises because there is an error in your code, (i.e. endless loop, dead-lock), and the Interrupt is some other thread's method for dealing with that error.
If you know there is rational cleanup to be done, then do it. If you know a deeper cause for the Interrupt, you can take on more comprehensive handling.
So in summary your choices for handling should follow this list:
By default, add to throws.
If not allowed to add to throws, throw RuntimeException(e). (Best choice of multiple bad options)
Only when you know an explicit cause of the Interrupt, handle as desired. If your handling is local to your method, then reset interrupted by a call to Thread.currentThread().interrupt().
To me the key thing about this is: an InterruptedException is not anything going wrong, it is the thread doing what you told it to do. Therefore rethrowing it wrapped in a RuntimeException makes zero sense.
In many cases it makes sense to rethrow an exception wrapped in a RuntimeException when you say, I don't know what went wrong here and I can't do anything to fix it, I just want it to get out of the current processing flow and hit whatever application-wide exception handler I have so it can log it. That's not the case with an InterruptedException, it's just the thread responding to having interrupt() called on it, it's throwing the InterruptedException in order to help cancel the thread's processing in a timely way.
So propagate the InterruptedException, or eat it intelligently (meaning at a place where it will have accomplished what it was meant to do) and reset the interrupt flag. Note that the interrupt flag gets cleared when the InterruptedException gets thrown; the assumption the Jdk library developers make is that catching the exception amounts to handling it, so by default the flag is cleared.
So definitely the first way is better, the second posted example in the question is not useful unless you don't expect the thread to actually get interrupted, and interrupting it amounts to an error.
Here's an answer I wrote describing how interrupts work, with an example. You can see in the example code where it is using the InterruptedException to bail out of a while loop in the Runnable's run method.
I just wanted to add one last option to what most people and articles mention. As mR_fr0g has stated, it's important to handle the interrupt correctly either by:
Propagating the InterruptException
Restore Interrupt state on Thread
Or additionally:
Custom handling of Interrupt
There is nothing wrong with handling the interrupt in a custom way depending on your circumstances. As an interrupt is a request for termination, as opposed to a forceful command, it is perfectly valid to complete additional work to allow the application to handle the request gracefully. For example, if a Thread is Sleeping, waiting on IO or a hardware response, when it receives the Interrupt, then it is perfectly valid to gracefully close any connections before terminating the thread.
I highly recommend understanding the topic, but this article is a good source of information: http://www.ibm.com/developerworks/java/library/j-jtp05236/
I would say in some cases it's ok to do nothing. Probably not something you should be doing by default, but in case there should be no way for the interrupt to happen, I'm not sure what else to do (probably logging error, but that does not affect program flow).
One case would be in case you have a task (blocking) queue. In case you have a daemon Thread handling these tasks and you do not interrupt the Thread by yourself (to my knowledge the jvm does not interrupt daemon threads on jvm shutdown), I see no way for the interrupt to happen, and therefore it could be just ignored. (I do know that a daemon thread may be killed by the jvm at any time and therefore are unsuitable in some cases).
EDIT:
Another case might be guarded blocks, at least based on Oracle's tutorial at:
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html

is Thread.sleep() guaranteed to wait?

Consider this scenario:
I want to make several web service calls consecutively. I am only allowed to make a call every 10 seconds. I have something like this:
while(true) //we will break inside the loop eventually
{
//...
try {
Thread.sleep(10000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
//make web service call here
//...
}
As you can see, This will (hopefully) make a call approximately every 10 seconds. But my concern is that while Thread.sleep() is executing, I will get interrupted before 10 seconds and I will subsequently make a web service call that will get ignored.
This is not a multithreaded application so it runs on its own JVM. This is the only thread I am not calling interrupt() on this thread from anywhere, but I am not sure if I will run into trouble with my host machine's thread scheduler or anything.
Accuracy of timekeeping is not of great importance. I especially don't care if the 10 seconds turns into 15 seconds. But if somehow Thread.Sleep throws too soon I will be in trouble.
Is this the proper way of implementing this behaviour?
To clarify:
1- this is NOT a multi-threaded program
2- I do NOT want to do a exact times, the timing can be inaccurate as long as an unexpected exception does not get me out of the try block prematurely
I am not sure if I will run into trouble with my host machine's thread scheduler
No, the runtime will not interrupt an application thread for any reason. Only other code in your application (or code that you drag in with some framework that you choose) will interrupt threads.
Every task should specify an interruption policy: what will happen if the thread is interrupted? An application should never interrupt a thread without understanding its interrupt policy and being prepared to deal with the consequences.
So, define the interrupt policy for your thread. In your application, it is something you don't expect to happen, and if someone adds code to your application that calls interrupt() on your thread, they introduced a bug. Basically, your policy is that interruption isn't allowed. So, throwing a some unchecked exception, like IllegalStateException is a valid response.
Is this the proper way of implementing this behaviour?
No, it's not. When you are interrupted, you should signal callers that you were interrupted. This should be done by letting an InterruptedException propagate back to the caller (or a application-defined exception with similar meaning), or by restoring the interrupt status on the current thread. Suppose your interruption policy permits interruption, by terminating the loop prematurely. You should still restore the interrupt status:
while(true) {
...
try {
Thread.sleep(10000);
} catch(InterruptedException abort) {
Thread.currentThread().interrupt();
break;
}
/* Make web service call here... */
}
No, it is not guaranteed to wait for at least 10 seconds. The whole point of the sleep method throwing the checked exception InterruptedException is the possible need to end the sleep before the 10 seconds are up, by interrupting the thread.
You are wrong to focus on your program being "single threaded". In practice there is no such thing: the JVM and the JRE are permitted (and in fact do) run additional threads. The Thread.sleep() API says that the method throws InterruptedException if the sleeping thread is interrupted by another thread; it does not specify that only "user" threads are permitted to interrupt the sleeping thread.

How can I immediately terminate a Thread? (Not interrupt)

This is not a question about how to cleanly terminate a thread, ie by calling interrupt on it and having the thread respond appropriately. I cannot modify code the thread is executing in any way.
I specifically want to immediately terminate a Thread, I don't care at all what state things are left in. I know something similar is possible using Thread.stop, however this actually throws a ThreadDeath exception, and for the Thread to terminate this exception cannot be caught. However the code I am dealing with catches this exception and is not rethrowing it.
Thread.destroy() seemed to be what I was looking for, however this method was never implemented. Is there any other way of achieving this?
I believe that there's no way in Java to just kill off a thread like you're describing. As you note in a comment, interrupt won't do what you want. If the thread is executing, it just sets a flag and it's up to the thread to notice it. if the thread is waiting or sleeping, it will throw an InterruptedException.
The only way I can imagine doing what you're describing is to kill the process in which the thread is running. (E.g., call System.exit(int).)
No there isn't a way. From Java Concurrency in Practice:
Since there is no preemptive way to stop a thread, they must instead
be persuaded to shut down on their own.
Interrupting a thread is not the cleaner way as you said. Clean ways could be:
ExecutorService.shutdown()
Future.cancel()
Poison Pills
You aren't meant to submit tasks to threads that take ages to be done. You would rather divide them into smaller tasks and send a poison pill to cancel the bigger task. If there is not a way to do that, then spawn/fork a process and kill it if you want to cancel the task.
If you don't trust the thread in question to the point that you need to kill it, you would probably be better off running it in a separate process, and kill the process instead.
Anyway, the following code might work if you are ok with the deprecated Thread methods:
while (theThread.isAlive()) {
theThread.stop();
}
Depending on how badly the thread is trying to survive…
You might want to run this code in several threads or repeat the stop() call if that's not enough. However, I managed to kill the following thread with this code:
final Thread iWontDie = new Thread(() -> {
int i = 0;
while (true) {
try {
System.out.println("I'm still alive! " + ++i);
} catch (Throwable t) {
// eat t
}
}
});
iWontDie.start();
If you are on Java 7 or earlier, you could use the overloaded stop(Throwable obj) method to throw something besides a ThreadDeath error:
Forces the thread to stop executing. If the argument obj is null, a NullPointerException is thrown (in the current thread). The thread represented by this thread is forced to stop whatever it is doing abnormally and to throw the Throwable object obj as an exception. This is an unusual action to take; normally, the stop method that takes no arguments should be used.
This method, like the parameterless version, is deprecated, so just keep that in mind.

Handling InterruptedException while waiting for an exit signal (bug in Android?)

I've come across the code below, and I'm wondering if it does exactly what I think it does:
synchronized(sObject) {
mShouldExit = true;
sObject.notifyAll()
while (!mExited) {
try {
sObject.wait();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
About the context: there is another thread that checks for mShouldExit (inside the sObject monitor) and will exit in that case.
This does not look to be a correct pattern to me. If an interrupt happens, it will set the interrupted status again, so when it returns to sObject.wait(), another InterruptedException will come etc. etc. etc. Therefore, it can never go to truly waiting state (sObject.wait()) i.e. it will never release the sObject monitor. This may result in an infinite loop, as the other thread cannot set mExiting to true, because it can never enter sObject's monitor. (So I think that the interrupt() call is an error, it must not be used here.) Am I missing something?
Note that the code snippet is a part of the official Android framework source code.
UPDATE: actually, the situation is worse, because the same pattern is used in Android when your GL rendering starts. The official source code of GLSurfaceView.GLThread.surfaceCreated():
public void surfaceCreated() {
synchronized(sGLThreadManager) {
if (LOG_THREADS) {
Log.i("GLThread", "surfaceCreated tid=" + getId());
}
mHasSurface = true;
sGLThreadManager.notifyAll();
while((mWaitingForSurface) && (!mExited)) {
try {
sGLThreadManager.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
You can reproduce the bug in a similar way: make sure your UI thread has its interrupted status flag yet, then add your GLSurfaceView and start the GL rendering (via setRenderer(...), but on some devices, make sure your GLSurfaceView has Visibility.VISIBLE status, otherwise rendering will not start).
If you follow the above steps, your UI thread will end up in an infinite loop, because the above-quoted code will keep generating an InterruptedException (due to wait()) and therefore the GL thread will never be able to set mWaitingForSurface to false.
According to my tests, it seems that such an infinite loop will also result in an endless sequence of GC_CONCURRENT garbage collection (or, at least, such messages in logcat). Interesting, someone had an unknown poorly-defined issue on stackoverflow earlier which might be related:
How to solve GC_concurrent freed?
Isn't it possible that perhaps his UI thread had its interrupted flag set to true, and he was using a GLSurfaceView for the map he mentions? Just an assumption, a possible scenario.
Short version: That code is wrong, and will cause an infinite loop (I still have a doubt, but may depend on JVM implementations). Setting the interrupt status is the right thing to do, but it should then exit the loop, eventually checking that same interruption status using Thread.isInterrupted().
Long version for the casual reader:
The problem is how to stop a thread that is currently executing some work, in response to a "Cancel" button from the user or because of some other application logic.
Initially, Java supported a "stop" method, that preemptively stopped a thread. This method has been demonstrated to be unsafe, cause didn't give the stopped thread any (easy) way to clean up, release resources, avoid exposing partially modified objects and so on.
So, Java evolved to a "cooperative" Thread "interruption" system. This system is quite simple : a Thread is running, someone else calls "interrupt" on it, a flag is set on the Thread, it's Thread responsibility to check if it has been interrupted or not and act accordingly.
So, correct Thread.run (or Runnable.run, of Callable etc..) method implementation should be something like :
public void run() {
while (!Thread.getCurrentThread().isInterrupted()) {
// Do your work here
// Eventually check isInterrupted again before long running computations
}
// clean up and return
}
This is fine as long as all the code your Thread is executing is inside your run method, and you never call something that blocks for a long time ... which is often not the case, cause if you spawn a Thread is because you have something long to do.
The simplest method that block is Thread.sleep(millis), it's actually the only thing it does : it blocks the thread for the given amount of time.
Now, if the interrupt arrives while your thread is inside Thread.sleep(600000000), without any other suport, it would take a lot for it to arrive to the point where it checks isInterrupted.
There are even situations where your thread would never exit. For example, your thread is computing something and sending results to a BlockingQueue with a limited size, you call queue.put(myresult), it will block until the consumer free some space in the queue, if in the mean time the consumer has been interrupted (or died or whatever), that space will never arrive, the method will not return, the check on .isInterrupted will never be performed, your thread is stuck.
To avoid this situation, all (most) methods that interrupt the thread (should) throw InterruptedException. That exception simply tells you "I was waiting for this and that, but in the meanwhile the thread as been interrupted, you should do cleanup and exit as soon as possible".
As with all exceptions, unless you know what to do, you should re-throw it and hope that someone above you in the call stack knows.
InterruptedExceptions are even worse, since when they are thrown the "interrupted status" is cleared. This means that simply catching and ignoring them will result in a thread that usually does not stop :
public void run() {
while (!Thread.getCurrentThread().isInterrupted()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Nothing here
}
}
}
In this example, if the interrupt arrives during the sleep() method (which is 99.9999999999% of the time), it will throw InterruptedException, clear the interrupt flag, then the loop will continue since the interrupt flag is false, and the thread will not stop.
That's why if you implement your "while" correctly, using .isInterrupted, and you really need to catch InterruptedException, and you don't have anything special (like cleanup, return etc..) to do with it, least that you can do is set the interrupt flag again.
The problem in the code you posted is that the "while" relies solely on mExited to decide when to stop, and not ALSO on isInterrupted.
while (!mExited && !Thread.getCurrentThread().isInterrupted()) {
Or it could exit when interrupted :
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return; // supposing there is no cleanup or other stuff to be done
}
Setting the isInterrupted flag back to true is also important if you don't control the Thread. For example, if you are in a runnable which is being executed in a thread pool of some kind, or inside any method anywhere you don't own and control the thread (a simple case : a servlet), you don't know if the interruption is for "you" (in the servlet case, the client closed the connection and the container is trying to stop you to free the thread for other requests) or if it's targeted at the thread (or system) as a whole (the container is shutting down, stopping everything).
In that situation (which is 99% of the code), if you cannot rethrow the InterruptedException (which is, unfortunately, checked), the only way to propagate up the stack to the thread pool that the thread has been interrupted, is setting the flag back to true before returning.
That way, it will propagate up the stack, eventually generating more InterruptedException's, up to the thread owner (be it the jvm itself, of an Executor, or any other thread pool) that can react properly (reuse the thread, let it die, System.exit(1) ...)
Most of this is covered in chapter 7 of Java Concurrency in Practice, a very good book that I recommend to anyone interested in computer programming in general, not just Java, cause the problems and the solutions are similar in many other environments, and explanations are very well written.
Why Sun decided to make InterruptedException checked, when most documentation suggests to rethrow it mercilessly, and why they decided to clear the interrupted flag when throwing that exception, when the proper thing to do is setting it to true again most of the time, remains open for debate.
However, if .wait releases the lock BEFORE checking for the interrupt flag, it open a small door from another thread to modify the mExited boolean. Unfortunately the wait() method is native, so source of that specific JVM should be inspected. This does not change the fact that the code you posted is coded poorly.

When should a method throw InterruptedException, and how should I handle one that does? (blocking method)

If a method must be a blocking method, am I right in thinking that if I leave
out throws InterruptedException, I have made a mistake?
In a nutshell:
A blocking method should include throws InterruptedException otherwise is a normal method.
A blocking method can compromise responsiveness because it can be hard to predict when it will complete that's why it needs throws InterruptedException.
Is that correct?
No, I don't find your summary to be correct. Usually, if you're writing a method that calls on others that throw InterruptedException, then your method should also advertise throwing InterruptedException—unless you have a good plan for what to do when the methods on which yours relies signal interruption.
The cases where you'll be able to absorb such interruption are rare. Perhaps you're computing an iterative solution, where the precision increases with time, but, upon your calling thread being interrupted, you decide that the solution you've reached in the allotted time is good enough, and is still correct enough to return. In other words, that solution is still within your method's range.
Imagine:
private double improveUpon(double start) throws InterruptedException {
// ...
}
public double compute() {
double result = 0.0;
try {
do {
result = improveUpon(result);
} while (couldBeImproved(result));
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
return result;
}
Alternately, if you merely want to respect an interruption request, you can do so without InterruptedException being involved:
private double improveUpon(double start) {
// ...
}
public double compute() {
final Thread current = Thread.currentThread();
double result = 0.0;
do {
result = improveUpon(result);
} while (couldBeImproved(result) &&
!current.isInterrupted());
return result;
}
For yet another variation, consider the case where your method must either complete all its work or indicate to the caller that it could not complete it, and it takes a while to get there, but you want to respect thread interruption. Something like this will suffice:
private double improveUpon(double start) {
// ...
}
public double compute() throws InterruptedException {
final Thread current = Thread.currentThread();
double result = 0.0;
do {
if (current.interrupted())
throw new InterruptedException();
result = improveUpon(result);
} while (!isAdequate(result));
return result;
}
Note there that we called on Thread#interrupted(), which has the side effect of clearing the thread's interruption status if it had been set. If that method returns true, we as the caller have accepted the responsibility to hold and communicate that interruption status. In this case, since we do not assume that we created the calling thread and we don't have enough scope visible here to know what its interruption policy is, we communicated the interruption status we observed and adopted by throwing InterruptedException.
Labeling a method as "blocking" is always a matter of degree; every method blocks its caller for some amount of time. The distinction you may be looking for is whether the method blocks waiting on some external input, such as a user pressing a key or a message arriving over a network. In those cases, advertising that you throw InterruptedException indicates to your caller that your method is safe for use by callers from threads that must control their latency. You're saying, "This may take a while to complete, but it will take no longer than you're willing to wait." You're saying, "I'll run until you tell me not to." That's different from, say, java.io.InputStream#read(), which threatens to block until one of three conditions occur, none of which is the caller's thread being interrupted.
In most cases, your decision comes down to answering the following questions:
To satisfy my method's requirements, do I need to call on any methods that throw InterruptedException?
If so, is the work I've done up to that point of any use to my caller?
If not, I too should throw InterruptedException.
If nothing I call throws InterruptedException, should I respect my calling thread`s interruption status?
If so, is any work I've done up to the point at which I detect that I've been interrupted of any use to my caller?
If not, I should throw InterruptedException.
The situations in which one will detect the current thread's interruption and swallow it are usually confined to those where you, the author, created the thread in question, and you have committed to exiting the thread's run() method once the thread gets interrupted. That's the notion of "cooperative cancellation," wherein you observe the request for your thread to stop running, and you decide to abide by that request by finishing your work as quickly as possible and letting the thread's call stack unwind. Again, though, unless you're the author of the thread's run() method, you swallowing the thread's interruption status is likely harming the intended behavior of your callers and of the other methods upon which they call.
I suggest that you study the topic of a thread's interruption status, and get comfortable with the methods Thread#isInterrupted(), Thread#interrupted(), and Thread#interrupt(). Once you understand those, and see that an InterruptedException being in flight is an alternate representation of Thread#isInterrupted() having returned true, or a courteous translation of Thread#interrupted() having returned true, this should all start making more sense.
If you need more examples to study, please say so and I can add recommendations here.
InterruptedException is (usually) thrown when thread blocked on a method gets interrupt() called on it.
The point of it is to unblock (for some reason) a thread that is blocked. Example of reason is application shutdown. So, 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.
Threads can be interrupted because of some other reasons, but the point is the same.
If you have multi-threaded application you have to establish protocol for your threads so that they know when there is some special condition how to handle it. In case the thread is waiting/sleeping, you have to wake it up to handle the situation.
The clinets of your library or framework do not know anytrhing about your protocol, so they don't know how to handle InterruptedException because of that the recomendation is to handle it in your library/framework code.
If your method blocks, it should catch and handle InterruptedException, and prefer not to re-throw it.
Also, the method may block in several places - each place should catch and handle InterruptedException in a way appropriate for the place where it could be thrown.
The bible on the subject of multi-threaded code is Java Concurrency in Practice. I highly recommend you read it.
Edited:
When designing your concurrent code, realise that:
According to the JVM spec, InterruptedException may be thrown randomly by the JVM for no reason at all (known as a "spurious wakeups")
Many threads may be waiting on the same condition, all may be woken (eg by notifyAll()), but only one may advance when interrupted
so whenever a thread is woken, it should check the state of the wait condition it is waiting for and potentially go back to waiting.
Thus, properly written concurrent code should catch InterruptedException. You can chose to re-throw it or throw your own application-specific exception. "Application code" methods should prefer to throw "application" exceptions, however if your waiting code may find itself in a state where it's not possible to figure out "what went wrong", then your only option is to throw InterruptedException.

Categories

Resources