In Brian Goetz's article on how to handle InterruptedException, one paragraph stands out:
The one time it's acceptable to swallow an interrupt is when you know the thread is about to exit. This scenario only occurs when the class calling the interruptible method is part of a Thread, not a Runnable.
I don't get this. Is the reason something to do with the Runnable possibly being handled by a threadpool whereas the Thread is something you start on your own ?
Basically. The concern expressed in the article is that if you swallow the interupt exception then calling code higher in the stack won't know about the interuption, possibly causing undesirable behavior. If you start the thread, then you know there is nothing higher in the call stack that cares about being interupted, this thread will not continue to live in a thread pool, so just let the thread die.
I hate InterruptedException, I think it gives checked exceptions a bad name, and this article doesn't change that perspective. If it was so important that this exception pass up the call stack, Runnable.run() should have it declared in the method declaration so you can simply rethrow it, or it should have been an unchecked exception for the same reason SecurityException is an unchecked exception.
My prefered design would be that the methods return a boolean if they were interrupted if you care to know, but this article does make the case that that wouldn't necessarily be practical.
I would argue that extending Thread there was unnecessary, and therefore implementing Runnable is preferred.
But the important thing is that the code knows the thread is going to exit. If your code is part of some generic callback interface then you can't know how you are being used. You could be passed to a thread pool (indeed, we probably should be using pools rather than constructing Threads at inappropriate points in the code). OTOH, usually the Runnable is an anonymous inner class and therefore, at a source level, part of the enclosing method that does know what is going on.
So, if the thread is about to exit, resetting the interrupt state on the current thread is pointless because there is nothing to interrupt.
At some point you are going to want to say that it has interrupted enough. Thread pools for instance can continue to use a thread even after a task has been interrupted, although they might want to keep the InterruptException around for the callers that attempt to pick up the task.
Libraries generally do not handle interrupts correctly. IMO, interrupts don't have the context to make sense. Life would be a lot simpler without them, unfortunately they make their presence felt.
I agree with the others that the difference is whether you control that thread or not. If you extended a Thread, it's pretty much a given that you have control over that thread. On the other hand, if your code is simply a Runnable, it might be run on a borrowed thread (like from a thread pool) you do not own. By eating up the exception and not restoring the interrupt status, you deprive the code higher-up of the chance to recognize and act on the interruption.
InterruptedException being a checked exception is, I think, a good thing. An InterruptedException is a way to request a cancellation of tasks. Suppose one wrote a task in the form of a Runnable that involves a blocking method that throws an InterruptedException. If it were not a checked exception, if you're not being careful you may not think to act on the InterruptedException (thus cancellation) and do your own clean-up.
public class MyTask implements Runnable {
public void run() {
while (someCondition) {
Object value = someBlockingQueue.take();
// act on the value and loop back
}
}
}
Since InterruptedException is a checked exception, how my task should respond to interruption (cancellation) is front and center.
public class MyTask implements Runnable {
public void run() {
while (someCondition) {
try {
Object value = someBlockingQueue.take();
// act on the value and loop back
} catch (InterruptedException e) {
// I'm being cancelled; abort
cleanUp();
// restore the interrupt
Thread.currentThread().interrupt();
break;
}
}
}
}
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
This IBM developerWorks article states:
“The one time it is acceptable to swallow an interrupt is when you know the thread is about to exit. This scenario only occurs when the class calling the interruptible method is part of a Thread, not a Runnable […]”.
I always implemented Runnable for my threads by now. Giving a Runnable implementation like this:
public class View() implements Runnable {
#Overload
public void run(){
Thread worker = new Thread(new Worker());
worker.start();
do{
try{
TimeUnit.SECONDS.sleep(3);
updateView();
}catch(InterruptedException e){
worker.interrupt();
// Thread.currentThread().interrupt();
return;
}
}while(true);
}
protected void updateView(){
// …
}
}
Is it really necessary to call Thread.currentThread().interrupt(); right before my return; statement? Doesn’t return; perform a clean enaugh exit already? What’s the benefit of calling it? The article states that it should be done because otherwise “[…] code higher up on the call stack won't be able to find out about it […]”. What’s the benefit of a thread in Thread.State.TERMINATED with interrupted flag set over one without it upon application shutdown? Can you give me an example where code outside the Runnable inspects the interrupted flag for a sensible reason?
BTW, is it a better code design to extend Thread instead of implementing Runnable?
It resets the interrupt flag. This JavaSpecialists newsletter covers this confusing topic in more detail.
In my example, after I caught the InterruptedException, I used
Thread.currentThread().interrupt() to immediately interrupted the
thread again. Why is this necessary? When the exception is thrown, the
interrupted flag is cleared, so if you have nested loops, you will
cause trouble in the outer loops
So if you know that your code is not going to be used by another component, then you don't need to re-interrupt. However I really wouldn't make that minor optimisation. Who knows how your code is going to be used/reused in the future (even by copy/paste) and consequently I would reset the flag for every interrupt.
Here is an example where return it is not enough:
public void doSomething1() {
while (someCondition1()) {
synchronized {
try {
this.wait();
} catch (InterruptedException e) {
return; // Should be Thread.currentThread().interrupt();
}
}
}
}
public void doSomething2() {
while (someCondition2()) {
doSomething1();
}
}
As the exception throw clears the interrupted state next time doSomething1() is executed the status is cleared and the thread does not terminates.
I prefer extending Thread because it gives you a better understanding of what the thread is doing, but it is not necessarily better code design.
As Brian stated ,it resets the interrupt flag but that doesn't say much. In your case it will do nothing and the View-Thread will keep on running.
When interrupting a Thread, the standard procedure is that the Thread should stop running. It won't do this automatically and you have to implement a way to stop it once it is interrupted.
Using the built-in functionality there are two options:
Have the main loop inside the try-block for the InterruptedException. This way, when it is interrupted you you will be thrown out of the loop and the method will exit.
The above can be bad if you have to save the state as it may corrupt the state. As an alternative, you can set the interrupted-flag (as said when it's thrown. re-interrupt it Interrupt the Thread
Either way, you have to check that the Thread is interrupted in your while-loop (with !Thread.currentThread().isInterrupted()-statement in the while-loop) or it may/will not exit. You're not fulfilling one of the first options and neither checking the flag, so your View-thread will keep on running after being interrupted.
Is it really necessary to call Thread.currentThread().interrupt(); right before my return; statement?
As a point, I always do. We all copy-and-paste code and swallowing the interrupt is such a serious problem that I as a rule always do it, even if the thread is about to die.
Doesn’t return; perform a clean enough exit already?
If you are sure that it is the last return before the run() method completes and the thread exits, then yes, it not technically necessary. But see above. For posterity, return; doesn't do anything with the interrupt flag.
The question is whether your View class has been wrapped. Are you sure that when you return you are exiting the Thread. Maybe someone is delegating to it. AOP may be in place to do some sort of instrumentation.
What’s the benefit of calling it? The article states that it should be done because otherwise “[…] code higher up on the call stack won't be able to find out about it […]”.
In general, it is important to not swallow the interrupt when your code is called by some sort of wrapping code (delegation, AOP, etc) which needs the interrupt flag. If you are swallowing it, the wrapper won't be able to use it. But in this case, there is no benefit.
What’s the benefit of a thread in Thread.State.TERMINATED with interrupted flag set over one without it upon application shutdown?
Nothing. Once the thread exits the interrupt state is worthless. And actually, it looks like the interrupt state isn't even persisted after the thread is dead.
Thread thread = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("caught");
}
}
});
thread.start();
thread.interrupt();
System.out.println(thread.isInterrupted());
thread.join();
System.out.println(thread.isInterrupted());
Prints:
true
caught
false
Can you give me an example where code outside the Runnable inspects the interrupted flag for a sensible reason?
I can't. There is no code outside of the thread's run() method unless someone is wrapping your runnable in other code without your knowledge.
This may happen if you are using an ExecutorService but in that case the thread's interrupt status is specifically cleared with a wt.isInterrupted() before the job is run.
So again, the reason is to do is is because it's a good pattern and that's what's important in software engineering.
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.
I am trying to stop a thread. while stopping my thread i got thread interrupted exception.
What I can do if thread throw interrupted exception. should i catch it and do nothing or do i need to do anything?
You should not 'just stop' a thread. The thing I mostly do is create a public (perhaps static) variable in the Thread's class that indicates when the thread should stop. So something like a declaration of
public volatile bool shouldStop = false;
Then, at the end of every cycle of your thread, you could check if you need to quit (break from the while-loop or something).
Threads can be very annoying to handle! Calling interrupt/stop functions on just a thread itself is possible, but mostly unwanted.
There is a reason .stop() and .suspend() were deprecated and should not be used. This article is relevant:
http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
Also I quote the Javadocs:
Deprecated. This method is inherently
unsafe. Stopping a thread with
Thread.stop causes it to unlock all of
the monitors that it has locked (as a
natural consequence of the unchecked
ThreadDeath exception propagating up
the stack). If any of the objects
previously protected by these monitors
were in an inconsistent state, the
damaged objects become visible to
other threads, potentially resulting
in arbitrary behavior. Many uses of
stop should be replaced by code that
simply modifies some variable to
indicate that the target thread should
stop running. The target thread should
check this variable regularly, and
return from its run method in an
orderly fashion if the variable
indicates that it is to stop running.
If the target thread waits for long
periods (on a condition variable, for
example), the interrupt method should
be used to interrupt the wait. For
more information, see Why are
Thread.stop, Thread.suspend and
Thread.resume Deprecated?.
You should find some way (whether by some shared variable or otherwise) to synchronise your threads so the thread can end itself.
It depends on your needs. You can (for example) do something like this:
public void run() {
try {
// do thread stuff
} catch(ThreadInterruptedException ex) {
// close gracefully what needed to be closed
}
}
But the stop method is deprecated. So a better solution is to put some boolean variable to indicate whether the thread should stop or not and provide a method to change it in order to stop the thread (see this question for example).
In Brian Goetz's article on how to handle InterruptedException, one paragraph stands out:
The one time it's acceptable to swallow an interrupt is when you know the thread is about to exit. This scenario only occurs when the class calling the interruptible method is part of a Thread, not a Runnable.
I don't get this. Is the reason something to do with the Runnable possibly being handled by a threadpool whereas the Thread is something you start on your own ?
Basically. The concern expressed in the article is that if you swallow the interupt exception then calling code higher in the stack won't know about the interuption, possibly causing undesirable behavior. If you start the thread, then you know there is nothing higher in the call stack that cares about being interupted, this thread will not continue to live in a thread pool, so just let the thread die.
I hate InterruptedException, I think it gives checked exceptions a bad name, and this article doesn't change that perspective. If it was so important that this exception pass up the call stack, Runnable.run() should have it declared in the method declaration so you can simply rethrow it, or it should have been an unchecked exception for the same reason SecurityException is an unchecked exception.
My prefered design would be that the methods return a boolean if they were interrupted if you care to know, but this article does make the case that that wouldn't necessarily be practical.
I would argue that extending Thread there was unnecessary, and therefore implementing Runnable is preferred.
But the important thing is that the code knows the thread is going to exit. If your code is part of some generic callback interface then you can't know how you are being used. You could be passed to a thread pool (indeed, we probably should be using pools rather than constructing Threads at inappropriate points in the code). OTOH, usually the Runnable is an anonymous inner class and therefore, at a source level, part of the enclosing method that does know what is going on.
So, if the thread is about to exit, resetting the interrupt state on the current thread is pointless because there is nothing to interrupt.
At some point you are going to want to say that it has interrupted enough. Thread pools for instance can continue to use a thread even after a task has been interrupted, although they might want to keep the InterruptException around for the callers that attempt to pick up the task.
Libraries generally do not handle interrupts correctly. IMO, interrupts don't have the context to make sense. Life would be a lot simpler without them, unfortunately they make their presence felt.
I agree with the others that the difference is whether you control that thread or not. If you extended a Thread, it's pretty much a given that you have control over that thread. On the other hand, if your code is simply a Runnable, it might be run on a borrowed thread (like from a thread pool) you do not own. By eating up the exception and not restoring the interrupt status, you deprive the code higher-up of the chance to recognize and act on the interruption.
InterruptedException being a checked exception is, I think, a good thing. An InterruptedException is a way to request a cancellation of tasks. Suppose one wrote a task in the form of a Runnable that involves a blocking method that throws an InterruptedException. If it were not a checked exception, if you're not being careful you may not think to act on the InterruptedException (thus cancellation) and do your own clean-up.
public class MyTask implements Runnable {
public void run() {
while (someCondition) {
Object value = someBlockingQueue.take();
// act on the value and loop back
}
}
}
Since InterruptedException is a checked exception, how my task should respond to interruption (cancellation) is front and center.
public class MyTask implements Runnable {
public void run() {
while (someCondition) {
try {
Object value = someBlockingQueue.take();
// act on the value and loop back
} catch (InterruptedException e) {
// I'm being cancelled; abort
cleanUp();
// restore the interrupt
Thread.currentThread().interrupt();
break;
}
}
}
}