When working with threads in Java, dealing with InterruptedException seems to be a particular thorn in my side. I appreciate the fact that it's thrown when my threads are terminated, and thus offers me a chance to cleanup. What seems odd to me is that it's not an unchecked exception.
This creates the following problems:
a) If I want to use an existing framework in my threaded app, I'm forced to convert it to an exception the framework interface accepts. Thus the framework generally misinterprets it instead of either cleaning up or propagating it as it should.
b) Unless InterruptedException is rigorously declared for every call in the stack (and it's usually not because of a) ), it's difficult to cleanly shutdown.
If InterruptedException were instead unchecked, it seems that it would have a much higher likely hood of being used properly and resulting in clean shutdown of threads and apps in general. Why isn't it?
Interruption is supposed to be cooperative. I think the designers wanted to avoid a situation where you could blow away a thread by interrupting it, where the thread didn't have code to handle that eventuality. The intention seems to have been to make the Runnable code explicitly decide how to handle interruption. A lot of framework or language code seems to be about deciding whose responsibility something should be, and trying to make the correct usage apparent, in order to minimize how badly users get burned. This is one of those judgment calls.
With InterruptedException being checked, the worst case is that the exception is caught, but in a way that isn't awfully useful. (Actually the absolute worst case is the interrupt flag is not restored, leaving any following code in the thread unaware that the interruption happened.) If InterruptedException was unchecked (or if you wrap it in a RuntimeException, as shown in the article linked in the comments), the exception could go unhandled and proceed to terminate the thread, which could be really bad if the thread was not at a stopping place.
Toy examples and simple code would work better with unchecked InterruptedExceptions; nobody would bother with catching the exception and it would just work. However, in real code doing substantial work this was probably considered detrimental.
Making the exception checked is an attempt to ensure that the developer knows the exception can be thrown so that the developer can avoid the situation where the exception gets thrown in the middle of work the thread is doing, potentially leaving the work partially-done in a bad state.
Related
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
I've stumbled upon a situation where i have to deal with InterruptedException, but can't pass it upwards and don't feel that my code should be allowed to swallow it. To be precise, i'm working on a distributed lock implementation, and request to backing service may be interrupted or even time out - and, of course, java.util.concurrent.Lock doesn't account for such cases and doesn't allow me to spit out InterruptedException. I'm struggling to write correct implementation for non-throwing lock(), tryLock() and unlock() methods.
So, the question is - what would be correct strategy to handle case like this? From current point of view i see only three options (and i feel smell for every of them):
Ignore interrupted exception in lock / tryLock / unlock methods, retrying / returning false / assuming that even if request hasn't got to it's destination, TTL will eventually unlock record. This is obviously not the best solution because it hopes that everything will be good instead of dealing with problems.
Wrap in RuntimeException heir. This seems to be awful solution as well, since client code will have to work with concrete implementation rather than original interface, and unchecked exception certainly were not made for purpose like that.
Use the force Thread.currentThread().interrupt() call. I don't like this way because it basically tells thread to process it's own interrupt rather than pass a notice about call being interrupted; also, as far as i understand, if there's no outside polling, it will make thread eventually, but not instantly process interrupt, probably, in completely another place.
(And, of course there's an option to allow client code configure desired behavior, but that still doesn't provide me with a really good solution)
Is there any better way than any i've described? And if no, which one should be preferred over others?
Let me discuss each one of your available options.
Ignore interrupted exception
This is wrong. It is never right to swallow the exception when you are implementing something like a library which other users will come to rely upon. In these cases, it would never be prudent to swallow an exception unless you propagate it as a different exception which provides more meaningful information to the client. An InterruptedException is basically a request to cancel your thread and this information should never be suppressed from the client irrespective of whether the lock would be unlocked later. The client needs to know that someone wants the unit of work being carried out by this thread to be stopped.
Wrap in RuntimeException
No. This is wrong as well for exactly the same reason as above. the reason for propagating an InterruptedException is to let a client know that a request has been made to cancel an executing thread and hence wrapping it in a RuntimeException is wrong because this information is lost.
Use/force Thread.currentThread().interrupt() call
This may be right or wrong depending on the use case. Ask yourself if it would be ok for you to propagate the InterruptedException.
If it is ok to do so (it is not in your case but), then you can declare that your method throws InterruptedException and let the callers above worry about what needs to be done. This would typically be the case when you make a call to a method (say operation()) that throws an InterruptedException and you won't be able to proceed further unless this call completes. Suppose operation() throws InterruptedException then there is nothing much you can do other than propagating this exception. So you shouldn't catch the exception. In this case just declare that your method throws InterruptedException and you are done
If it is not ok to do so then the correct way to handle it would be to force an interrupt() call. Using this you suppress the exception but you still give the client the option of checking the flag to see if an interruption request was made. And you are right. This requires the client side to poll rather than processing the interruption. But this is not wrong. If you don't want clients to poll then propagating the exception would have been the better option. But this is not always possible and your example is one such use case. And there are many cases where a thread of execution can return some meaningful information even when it is Interrupted. So in this cases the exception is suppressed but the information that there was a request for termination can still be passed above by calling interrupt() method. So the client can either just use the result that was returned from a partial computation or poll to check if the interrupt flag was set depending on the use case. So you are giving the client more flexibility by doing this.
For me, the answer is almost always 3.
Java uses a cooperative interruption model: it feels like a very British approach to me:
I say, old chap, would you mind stopping what you are doing, if it is not too much trouble?
But there is no compunction to act upon the interruption in a timely way (or, indeed, at all). To use a Robin Williams quote:
Stop! ...or... I'll say stop again!
You can write your code to check for interruptions periodically, or not - it'd get very messy and repetitive if you did it everywhere. But, if you don't want to do anything when you are interrupted, you should at least preserve the fact that an interruption did occur, in order that calling code which does want to do something to act accordingly.
There is nothing really special about InterruptedException - it is literally an empty subclass of Exception. It is only typically only thrown in the first place if a particular method checks Thread.interrupted() or .isInterrupted(). So, I wouldn't worry about the fact that calling interrupt() doesn't immediately cause the thread to stop what it is doing - that is the very nature of cooperative interruption.
To qualify why I say "almost always" above: the Java tutorial describes interruption thus:
An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate.
I have only very, very rarely done anything other than wanting to terminate an interrupted thread.
If I wanted a thread "to do something else", I would likely be using an executor service anyway: each of the "things" to be done is represented by a separate Runnable, so I don't even know if they are done in the same thread anyway.
So I would typically interrupt the thread, and then throw a RuntimeException:
catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
Each Runnable just finishes what it is doing when interrupted; the executor service decided whether or not to do another task.
It is basically only if writing framework-level code (like an ExecutorService) that I would choose to continue after interruption.
It totally depends on your application, in particular on the meaning of an InterruptedException in your thread.
Option 1 for me is a bad practice: relying on other mechanisms make your code not clear and scary. You can always catch an exception and use only the finally method to release all the locked resources.
Then relaunching the exception or hiding it (probably returning a specific result) is up to you and the specific meaning that that exception has in your application.
I am writing a fairly large, multithreaded application, with many differing roles for threads (e.g. event processing, metrics, networking). Currently, if there is any inconsistency that cannot be handled, it will manifest itself as an exception. Since there's really no way to recover from some of them, I've been rethrowing it as a runtime exception of type ApplicationDeathException.
Any classes that need to handle shutdown would call it from a catch block for this exception, and then rethrow it in order for it to propagate up the stack).
I am considering killing off all other threads in this same manner by calling Thread#stop(Throwable) upon them. Most are fine with sudden termination, and can catch this exception should there be a need for shutdown logic. They will simply have the exception propagate up the stack, performing shutdown logic whereever needed, and eventually just killing the thread in the end. Are there any hidden dangers that I'm missing with this approach?
Thread.stop has been deprecated since it is unsafe (see the Javadoc). Instead have each thread monitor a boolean flag of some sort (see Java: How to stop thread? and likely countless other threads on SO).
In situations like this I typically implement some sort of thread pool manager that is responsible for cleanly shutting down running threads. Then when something really bad happens you only need to notify the manager to shut things down.
I am working on an application that at some point starts a worker thread. This thread's behaviour will vary greatly depending on the parameters used to start it, but the following list of properties apply:
It will do some minor I/O operations
It will spend minor time in 3rd party libraries
It may create some worker threads for a certain subtask (these threads will not be reused after their task is finished)
It will spend most of its time crunching numbers (there are no blocking calls present)
Due to the possible long duration (5 minutes up to several hours, depending on the input), we want to be able to abort the calculation. If we choose to abort it, we no longer care about the output, and the thread is in fact wasting valuable resources as long as it keeps running. Since the code is under our control, the advised way is to use interrupts to indicate an abort.
While most examples on the web deal with a worker thread that is looping over some method, this is not the case for me (similar question here). There are also very few blocking calls in this work thread, in which case this article advises to manually check the interrupt flag. My question is: How to deal with this interrupt?
I see several options, but can't decide which is the most "clean" approach. Despite my practical example, I'm mainly interested in the "best practice" on how to deal with this.
Throw some kind of unchecked exception: this would kill the thread in a quick and easy way, but it reminds me of the ThreadDeath approach used by the deprecated Thread#stop() method, with all its related problems. I can see this approach being acceptable in owned code (due to the known logic flow), but not in library code.
Throw some kind of checked exception: this would kill the thread in a quick and easy way, and alleviates the ThreadDeath-like problems by enforcing programmers to deal with this event. However, it places a big burden on the code, requiring the exception to be mentioned everywhere. There is a reason not everything throws an InterruptedException.
Exit the methods with a "best result so far" or empty result. Because of the amount of classes involved, this will be a very hard task. If not enough care is taken, NullPointerExceptions might arise from empty results, leading to the same problems as point 1. Finding these causes would be next to impossible in large code bases.
I suggest you check Thread.currentThread().isInterrupted() periodically at points you knwo it is safe to stop and stop if it is set.
You could do this in a method which checks this flag and throws a custom unchecked exception or error.
What about a use of ExecutorService to execute the Runnable? Checkout the methods wherein you can specify the timeout. E.g.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();
Here Task of course implements Runnable.
A quote from "Effective Java book" :
" The libraries provide the Thread.stop method, but this method was
deprecated long ago because it is inherently unsafe—its use can result
in data corruption. Do not use Thread.stop"
Anyone can tell me why ?
What if the thread you stop holds a critical lock? What if the thread has placed an object into an inconsistent state and hasn't had a chance to restore it yet? The correct way to stop a thread is with its cooperation, not by forcing it to stop from the outside.
Also, it simply doesn't make logical sense. All the threads in an application are supposed to be cooperating to achieve the same ends. If there's something that shouldn't be done, no thread should do it. There should be no reason to stop a thread -- it should only be coded to do something if that is something the application as whole needs done in the first place. If a thread needs to be stopped, it's only because the code it is running is broken -- doing things even if they should not be done. Just fix that code.
From the javadoc:
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock
all the monitors that it has locked. (The monitors are unlocked as the
ThreadDeath exception propagates up the stack.) If any of the objects
previously protected by these monitors were in an inconsistent state,
other threads may now view these objects in an inconsistent state.
Such objects are said to be damaged. When threads operate on damaged
objects, arbitrary behavior can result. This behavior may be subtle
and difficult to detect, or it may be pronounced. Unlike other
unchecked exceptions, ThreadDeath kills threads silently; thus, the
user has no warning that his program may be corrupted. The corruption
can manifest itself at any time after the actual damage occurs, even
hours or days in the future.
For more information, read this:
http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
IMHO, It's only unsafe if you use it to stop another thread. You can use it to stop the current thread without the normal issues e.g. if you need to re-throw a checked exception.
The problem with stop(), is you have no idea where in the thread you are throwing the exception or error. The only time you would consider using it is to stop third party threads which are not behaving correctly. The problem is that such threads can catch and ignore the error this triggers. If you really have unsafe or unreliable code you need to run, I suggest you use a separate process which you can kill as required.
In a nutshell, stop aborts the thread forcibly without giving it any chance to clean up. The most typical outcome is a mess.