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.
Related
Is it good practice to use isInterrupted() method of the Thread to end a while loop in its run method, by calling its interrupt() method from outside.
public class ThreadManager{
...
...
Thread t;
public void init(){
t = new MyThread();
t.start();
}
.....
public void stopProcessing(){
t.interrupt();
}
}
public class MyThread extends Thread{
public void run(){
while( !isInterrupted()){
try{
//.. some process in a loop
}catch(InterruptedException e){
// now stop running and end run method
}
}
}
}
Basically and in most cases, yes. It is a good practice to use isInterrupted() as a condition in while loop, but that's usually not all you need to do.
In many cases, you also need to catch InterruptedException which signals that interrupt() was called. One of these cases might be using of Thread.sleep() in the loop. If thread is sleeping or waiting, this exception must be caught. You can use for example break in the catch block.
public void run() {
while(!isInterrupted()) {
try {
...
sleep(1000L);
} catch (InterruptedException ex) {
break;
}
}
}
That's probably a matter of opinion. In my opinion (and that's all it is), Yes, using interrupt as a means to signal a thread to shut down is a good idea.
I seldom ever get to write the top level of any application. I write library code. I always assume that interrupt() means that my code should gracefully abort whatever it was asked to do, but that it should be prepared in case the top-level application asks it to do something again afterward.
If my code creates a thread, and an interrupt happens in the thread, I "abort" by having the thread shut itself down, but I make sure that my code can re-create the thread if needed.
That way, if the designer of the top-level app wants interrupt() to mean, "shut down the application," my code will work with that; but if the designer of the top-level app wants it to mean something different (e.g., abort the current command, and prompt a user for another), then my code will work with that too.
Occasionally we must forcibly stop a thread as a best effort before entirely shutting down the whole JVM. Usually Thread#stop is cited as a surefire, even if ham-handed and deprecated, way to unconditionally stop a thread. This is not so, however: all the rogue thread has to do to keep itself running is catch ThreadDeath or a superclass:
public static void main(String[] args) throws InterruptedException {
final Thread t = new Thread() { public void run() {
for (;;)
try { Thread.sleep(Long.MAX_VALUE); }
catch (Throwable t) {
System.out.println(t.getClass().getSimpleName() + ". Still going on...");
}
}};
t.start();
Thread.sleep(200);
t.interrupt();
Thread.sleep(200);
t.interrupt();
Thread.sleep(200);
t.stop();
Thread.sleep(200);
t.stop();
}
This will print
InterruptedException. Still going on...
InterruptedException. Still going on...
ThreadDeath. Still going on...
ThreadDeath. Still going on...
Is there anything else that I could do to really, really stop a thread without killing the whole JVM?
No. There is no built in simple way to really stop a thread.
Such a method, destroy, was planned but not implemented:
Deprecated. This method was originally designed to destroy this thread without any cleanup. Any monitors it held would have remained locked. However, the method was never implemented. If if were to be implemented, it would be deadlock-prone in much the manner of suspend(). If the target thread held a lock protecting a critical system resource when it was destroyed, no thread could ever access this resource again. If another thread ever attempted to lock this resource, deadlock would result. Such deadlocks typically manifest themselves as "frozen" processes.
Threads are not meant for that. They don't provide security. The other thread could just as well terminate the JVM itself - or spawn other problematic threads.
For more information, see Why are Thread.stop, Thread.suspend and Thread.resume are deprecated. You can read why here.
There is no way to guarantee that that thread can be stopped in Java. The most forceful way is Thread.stop but that's an accident waiting to happen. The alternatives are to use Thread.interrupt and having the thread check a flag but both of these rely on the thread being coded correctly and, in the case of the flag, checking it on a regular basis.
Personally, I would make sure I wasn't catching ThreadDeath. Stop is a poor way to stop a thread but at least you should get a notification as long as you aren't catching ThreadDeath.
instead of continuous checking of variable inside a loop:
class Tester {
public static void main() {
Try t = new Try();
Thread.sleep(10); //wait for 10 milliseconds
t.interrupt(); // 'interrupt' i.e stop the thread
}
}
public class Try extends Thread {
public void interrupt() {
//perform all cleanup code here
this.stop();
/*stop() is unsafe .but if we peform all cleanup code above it should be okay ???. since thread is calling stop itself?? */
}
}
In order to perform interrupt in a good manner you should poll for the "interrupted()" method inside the thread that is being interrupted.
Just be aware that calling interrupted() method resets the interruption flag (that is set when calling interrupt()).
I guess the bottom line is that you have to continuously poll inside the thread in order to perform a graceful interruption.
You should never ever call .stop() on a Thread, period. It's not enough for the thread to perform its own cleanup. Since calling .stop() immediately releases all monitors, other threads may see shared data in an inconsistent state which may result in almost impossible to track errors.
Use Thread.interrupt() method instead of Thread.stop(). In the interrupted thread you can catch the InterruptedException and do any cleanup required.
A similar questions has already been asked here, you can find a code sample there too.
If I have a function with a try/finally section, and the thread running it is interrupted while in the try block, will the finally block execute before the interruption actually occurs?
According to the Java Tutorials, "if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues."
Here's the full passage:
The finally block always executes when the try block exits. This
ensures that the finally block is executed even if an unexpected
exception occurs. But finally is useful for more than just exception
handling — it allows the programmer to avoid having cleanup code
accidentally bypassed by a return, continue, or break. Putting cleanup
code in a finally block is always a good practice, even when no
exceptions are anticipated.
Note: If the JVM exits while the try or catch code is being executed, then
the finally block may not execute. Likewise, if the thread executing
the try or catch code is interrupted or killed, the finally block may
not execute even though the application as a whole continues.
class Thread1 implements Runnable {
#Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("finally executed");
}
}
}
...
t1.start();
t1.interrupt();
It prints - finally executed
In the comments to the answer, #Risadinha asked very valid question about whether code in finally block gets executed if we restore interruption flag inside catch block by calling Thread.currentThread().interrupt().
Here is small code snippet to test:
final SomeContext context = new SomeContext();
Thread thread = new Thread() {
#Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
// this code gets executed even though
// we interrupt thread in catch block.
context.value = 9;
}
}
};
thread.start();
thread.interrupt();
thread.join(); // need to wait for thread code to complete
assertEquals(context.value, 9); // values are the same!
SomeContext class code:
class SomeContext {
public volatile int value = 10;
}
Many of Oracle's Java tutorials are helpful (I have answers referencing the guarded blocks page and the SAX introduction), but they are not necessarily authoritative, and some of them have mistakes or are incomplete. The quote referenced in the question conflates interruption with the JVM exiting, which is confusing.
First, thread interruption in Java has nothing to do with OS-level interrupts. Sharing a name creates opportunities for confusion but there is no connection.
Next, JVM exit obviously kills the thread without an opportunity to do any cleanup. If the process dies before the thread has gotten as far as the finally block, too bad. But there's no comparison to interruption. Nothing about interruption prevents finally blocks from completing.
A design principle of interruption is that acting on the interruption requires the cooperation of the thread being interrupted. The thread interrupted responds at its discretion, the interruption doesn't compel the thread to do anything. All calling Thread#interrupt() does is set a flag on the thread. Blocking methods like wait or sleep check the flag to see if they should wake up early. (InterruptedException is a checked exception so you can tell who throws it when, and your Runnable can plan for it.) Also any code can use Thread#isInterrupted() to check whether its thread has had the flag set.
When Thread#sleep() recognizes the interrupted flag is set, it clears the flag before throwing InterruptedException. When your thread catches an InterruptedException it's good manners to restore the flag using Thread.currentThread().interrupt(), just in case there is any other code running in that thread that needs to know about the interruption. This comes into play when you have more complex situations with nested synchronizers where, for instance, some deeply nested component could get its sleep interrupted, letting it stay cleared could prevent higher layers from knowing about the interruption. In a simple toy example like the ones in other answers here, it doesn't matter if the flag is restored or not, nothing checks it again and the thread terminates.
A Thread Interrupt in Java is just setting a flag. It doesn't cause anything special to happen to currently executing code, or affect the flow of control.
If your thread is engaged in, or attempts to enter, an operation that throws InterruptedException, then the exception is thrown from the point where that method is invoked and if it's inside a try block, the finally will execute before the exception leaves just like normal.
The effect of interruption is to throw an InterruptedException the next time a blocking operation occurs (in practice, the next time a method is called that specifies it can throw an InterruptedException), at which point -- as usual -- the normal try/catch execution flow is followed, which does indeed execute the finally block after the try and any applicable catches.
It will execute the same way as with any other exception from the try block, not before the interruption.
In the below code, i have a while(true) loop.
considering a situation where there is some code in the try block where the thread is supposed to perform some tasks which takes about a minute, but due to some expected problem, it is running for ever. can we stop that thread ?
public class thread1 implements Runnable {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
thread1 t1 = new thread1();
t1.run();
}
#Override
public void run() {
// TODO Auto-generated method stub
while(true){
try{
Thread.sleep(10);
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
First of all, you are not starting any thread here! You should create a new thread and pass your confusingly named thread1 Runnable to it:
thread1 t1 = new thread1();
final Thread thread = new Thread(t1);
thread.start();
Now, when you really have a thread, there is a built in feature to interrupt running threads, called... interrupt():
thread.interrupt();
However, setting this flag alone does nothing, you have to handle this in your running thread:
while(!Thread.currentThread().isInterrupted()){
try{
Thread.sleep(10);
}
catch(InterruptedException e){
Thread.currentThread().interrupt();
break; //optional, since the while loop conditional should detect the interrupted state
}
catch(Exception e){
e.printStackTrace();
}
Two things to note: while loop will now end when thread isInterrupted(). But if the thread is interrupted during sleep, JVM is so kind it will inform you about by throwing InterruptedException out of sleep(). Catch it and break your loop. That's it!
As for other suggestions:
About Thread.stop():
Deprecated. This method is inherently unsafe[...]
Adding your own flag and keeping an eye on it is fine (just remember to use AtomicBoolean or volatile!), but why bother if JDK already provides you a built-in flag like this? The added benefit is interrupting sleeps, making thread interruption more responsive.
The proper way to stop a thread is to interrupt it (stop() is deprecated and may have nasty side effects):
t1.interrupt()
This will cause an InterruptedException to be thrown by methods like Thread.sleep() or Object.wait().
Then just add a catch block for this exception and simply break out of the while loop.
EDIT: I now realised that your infinite loop is running within the main thread, there's no thread created by your code, it's just run()ning a Runnable. You need to call Thread.start() at some point to spawn a new thread.
Move the catch interrupt to outside the loop. This doesn't require any more lines of code, it just handles interrupts correctly i.e. the action is interrupted.
public void run() {
try{
while(true) {
Thread.sleep(10);
}
} catch(InterruptedException e){
System.out.println("Thread interrupted"));
}
}
The only way to stop an arbitrary thread is by interrupting it. Keep a reference to it then call the interrupt method.
Create a field boolean keepGoing that you set to true before starting your thread and replace while (true) with while (keepGoing). At some point, you decide where, simply change the value of keepGoing to false and it will exit the loop.
I recommend using Thread.interrupt() (as mentioned by #Bohemian). It has a couple of advantages over using ad-hoc flags:
You don't need to create and use an application-specific API to do this. (And interrupts are guaranteed thread-safe ...)
Thread.interrupt() will interrupt threads that are blocked in a wait() or a join, or possibly1 some blocking I/O calls.
However, it is not a magic bullet. If the thread you are trying to stop is executing regular code, it needs to periodically check its interrupted() flag, or it won't no to stop. This leaves us in the same as boat as we are in with an ad-hoc flag mechanism. The thread has to cooperate, or it can't be (safely) stopped.
1 - This is a murky area. On the one hand, there is an InterruptedIOException whose javadoc says "Signals that an I/O operation has been interrupted". On the other hand, the exception is not explicitly mentioned in the javadocs for the various java.io stream classes.
It is true that some 3rd-party code may not deal with the interrupted flag properly, and interrupts may get "eaten" as a result. But you can check for that if you have source code. And the situation is not a lot different to the 3rd-party code not paying attention to your ad-hoc flag mechanism.
I would NOT recommend using Thread.stop(). It is fundamentally flakey. Some people claim that it works for them, but IMO they are either dealing with a special case that works ... or they are being lucky.