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.
Related
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;
}
}
}
}
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.
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.
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.
I have a multi-threaded program, where I have one thread to watch over several threads. The functioning is designed like this:
Main program does initiation and starts Watcher Thread, in void Main(), I have the line
Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownThread(), "Exit Listener"));
When I don't start the watcher thread, the ShutdownThread is called when I terminate the program, but when I start the Watcher thread which has a dead loop in it, the ShutdownThread is not called (I print out a message in that thread). That is very very strange. Any explanations?
The watcher thread is like:
public void run(){
boolean running=false;
thread a=new thread(...); //Do the same thing for b, c, d...
while(true){
if (a.isActive()){
if (running)
thread a= new thread(...);
a.start();
running=true;
}
Thread.sleep(1000); //try catch block...
}
What I would like is a graceful shutdown, that upon getting a terminate signal, shutdownThread is run, sets a flag and interrupts all threads, and waits for the threads to interrupt it, or it timeout so that the remaining threads can be killed. All the threads can catch an interuption, and check if a flag is set, if set, it will interrupt shutdownThread and then exit itself. Instead what I am seeing is all the threads are terminating by itself, doing no cleanup at all.
How about using signals? Is there any good cross-platform code for that?
Then, setUncaughtExceptionHandler doesn't work either. I did testing, and found that the handler isn't called at all. I don't know why. The code for the handler is:
public static class ErrHandler implements Thread.UncaughtExceptionHandler{
public final void uncaughtException(Thread t, Throwable e) {
Error(t + "died, threw exception: " + e);
}
}//this is in public class globals
I hook it using
producer.setUncaughtExceptionHandler(Globals.errhandler);
Is in my code, and I only see the original e.printStack() instead. It seems that I can't override it, either in the parent thread, or in itself. This is so frustrating. I'm thinking of putting a Entry into a queue, and reading it elsewhere. At least that may work.
Oh, the whole purpose is to make sure that if any of the threads die because of runtime exceptions, the watcher thread will check whether the exception is fatal enough, and decide to restart that thread or to quit altogether. At the same time, I would like the program to end gracefully (an interrupt is sent to saver threads so that it dumps the results out, and then interrupts back to tell that we are ready to quit) when the user ends it.
Dunno if it helps you, but we encountered the same behaviour.
Not all exceptions are routed correctly to the registered ExceptionHandler.
I wonder if Unit-Tests exists at all for the concurrent framework. Because this had to be detected.
We implemented the ScheduledExecutorService by ourself by using a ScheduledExecutorService instance as delegate and encapsulate the parameter Runnable/Callable of each method in a Runnable/Callable implementation which corrects the behaviour.