416

How do you kill a java.lang.Thread in Java?

Jonas
  • 121,568
  • 97
  • 310
  • 388
flybywire
  • 261,858
  • 191
  • 397
  • 503
  • 2
    till now you can not kill a thread; because destroy() is never implemented due to dead-lock prone – AZ_ Jun 10 '11 at 14:14
  • 1
    I prefer the answer regarding `ExecutorStatus` on this question: http://stackoverflow.com/questions/2275443/how-to-timeout-a-thread – Kirby Jun 17 '11 at 01:17
  • 9
    @loungerdork "I think Java should implement a safe stop/destroy method for runaway threads that you have no control over, despite the caveats of losing locks and other pitfalls" So you want an *unsafe* thread stop. I think you already have one. – DJClayworth Jun 10 '15 at 14:41
  • 4
    It's amazing what kind of questions would get 212 upvotes in 2009. This would be immediately destroyed today. – Jonathon Reinhart Mar 11 '16 at 19:34
  • 8
    @JonathonReinhart: Why is that? It seems to be a legit question, even these days. Maybe you don't know the frustration it causes when you have runaway threads and can only use deprecated functions to handle this somehow? – TFuto May 07 '16 at 17:30
  • 1
    @JonathonReinhart AFAIK more and more services are becoming hybrid and use managed environment to execute 3rd party code (plugin, scripts, etc.) which they don't have fully control over the code, it seems unreasonable to completely take thread.stop off the table, since for service engineers, a live-and-serving state can be infinitely better than a non serving state either due to hanging (which takes away threads), or busy infinite looping (which takes away cores), the state corruption issue is not such a big deal for per-query-state, data-serving services whose data integrity is not paramount – Weipeng Oct 25 '18 at 18:53
  • I think it is interesting, because while(true) is a bit faster than while(running) but there is no way to get out of while(true) without checking a field somewhere in the loop. – neoexpert Feb 25 '19 at 12:35

17 Answers17

205

See this thread by Sun on why they deprecated Thread.stop(). It goes into detail about why this was a bad method and what should be done to safely stop threads in general.

The way they recommend is to use a shared variable as a flag which asks the background thread to stop. This variable can then be set by a different object requesting the thread terminate.

Ravi
  • 30,829
  • 42
  • 119
  • 173
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 1
    if you check the thread that you have interrupted isAlive() it will return you true and they will continue adding to your current ThreadGroup[], you can see this using Thread.currentThread.getThreadGroup().list(); it will prints all the threads its has and you will see multiple instances of your thread if you repeat your flow. – AZ_ Jun 10 '11 at 14:08
  • 3
    If you are on a PC then its no problem but if you are developing a software for mobile (android i have experienced it) then you will get OutOfMemoryError – AZ_ Jun 10 '11 at 14:09
  • and you can not remove it by ThreadGroup method void remote(Thread t) because its access is package private. but I personally think that you can call is using reflection. – AZ_ Jun 10 '11 at 14:11
  • 2
    It could/should be noted, that to ensure prompt communication of the stop-request via flag, the variable must be volatile (or access to the variable must be synchronized), as stated in the recommendation. – mtsz Jun 18 '11 at 19:32
  • 2
    That link has been killed at this point. I was able to find it on archive.org, though: http://web.archive.org/web/20090202093154/http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html – Jay Taylor Sep 27 '11 at 16:38
  • @codecompleting I spent about 3 years in college teaching and writing almost exclusively in Java ;) – JaredPar Nov 30 '11 at 22:15
  • 1
    And what if the thread is waiting for some response? eg a user input or socket to receive data? – Shashwat Mar 29 '14 at 06:57
  • 2
    I use method `getConnection()` from `java.sql.DriverManager`. If the connection attemt takes too long I try to kill the corresponding thread by calling `Thread.interrupt()` but it doesn't influence the thread at all. The `Thread.stop()` works however, although oracle says it shouldn't work if `interrupt()` doesn't. I wonder how make it work and avoid using deprecated method. – Danny Lo Apr 24 '14 at 14:42
  • http://stackoverflow.com/questions/19894607/java-how-to-stop-thread/19894733#19894733 – Trying Aug 21 '14 at 04:47
  • Ah, I miss Erlang so much. – Aetherus Jan 02 '20 at 03:01
132

Generally you don't..

You ask it to interrupt whatever it is doing using Thread.interrupt() (javadoc link)

A good explanation of why is in the javadoc here (java technote link)

Fredrik
  • 5,759
  • 2
  • 26
  • 32
  • @Fredrik What happens to the Thread context when `interrupt()` method is called? The main question is related [to log generation](http://logging.apache.org/log4j/2.x/faq.html#separate_log_files) for each new thread. – ABcDexter Sep 06 '16 at 05:51
  • 3
    @ABcDexter The whole point is that interrupt doesn't interrupt anything, it just signals to the code in the thread (or the code being called by the thread) that someone has asked it to interrupt whatever it is doing. The thread is then supposed to nicely stop the processing and return, just like if it was done doing what it should (and at that point, the thread context is probably also discarded). OTOH, had you really force stopped the thread, your question would be really good and the answer undefined. – Fredrik Sep 06 '16 at 06:50
67

In Java threads are not killed, but the stopping of a thread is done in a cooperative way. The thread is asked to terminate and the thread can then shutdown gracefully.

Often a volatile boolean field is used which the thread periodically checks and terminates when it is set to the corresponding value.

I would not use a boolean to check whether the thread should terminate. If you use volatile as a field modifier, this will work reliable, but if your code becomes more complex, for instead uses other blocking methods inside the while loop, it might happen, that your code will not terminate at all or at least takes longer as you might want.

Certain blocking library methods support interruption.

Every thread has already a boolean flag interrupted status and you should make use of it. It can be implemented like this:

public void run() {
   try {
      while (!interrupted()) {
         // ...
      }
   } catch (InterruptedException consumed)
      /* Allow thread to exit */
   }
}

public void cancel() { interrupt(); }

Source code adapted from Java Concurrency in Practice. Since the cancel() method is public you can let another thread invoke this method as you wanted.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Konrad Reiche
  • 27,743
  • 15
  • 106
  • 143
  • And what to do if you run untrusted code as a plugin or script? Java has embedded sandbox for untrusted code. And that sandbox is useless, it it allows to work without forceful stop. Imagine you are writing a browser on java. Ability to kill arbitrary page script is priceless. – ayvango Oct 25 '15 at 05:08
  • 1
    @ayvango Then you have to run that script in your own sandbox. The Java sandbox protects the machine from the application, not parts of the application from each other. – David Schwartz Aug 10 '16 at 10:08
  • @DavidSchwartz do you mean, that I just should use other platform then java? – ayvango Aug 16 '16 at 06:45
  • @ayvango You can still use the Java sandbox to protect the machine from your application. But if you want to protect parts of your application from other parts of your application, you'll need to choose some tool that can do that. – David Schwartz Aug 16 '16 at 16:58
  • @DavidSchwartz ASFAIK such tools could not exists if it is not supported on the platform level. But of course the task could be solved with fully interpreted script engine. It could count reductions like erlang does and do other stuff. – ayvango Aug 17 '16 at 05:59
  • 1
    I tried this but believe that "cancel()" is called from a different thread than "run()" and "interrupt()" is not available on a Runnable Class (Java 8). I ended up storing the thread handle to "volatile Thread runningThread" (thanks for the volatile point) and calling "runningThread.interrupt()" in "cancel()". – Dazed Dec 20 '17 at 12:03
  • `interrupted()` is designed for a thread to check (and clear) its own flag. Use it. `isInterrupted()` is used when checking *other threads'* flags; it leaves the flag alone because threads shouldn't change other threads' state. – John Kugelman May 08 '18 at 11:54
22

One way is by setting a class variable and using it as a sentinel.

Class Outer {
    public static volatile flag = true;

    Outer() {
        new Test().start();
    }
    class Test extends Thread {

        public void run() {
            while (Outer.flag) {
                //do stuff here
            }
        }
    }

}

Set an external class variable, i.e. flag = true in the above example. Set it to false to 'kill' the thread.

Nikhil Agrawal
  • 26,128
  • 21
  • 90
  • 126
karim79
  • 339,989
  • 67
  • 413
  • 406
  • 14
    This isn't reliable; make "flag" `volatile` to ensure it works properly everywhere. The inner class is not static, so the flag should an instance variable. The flag should be cleared in an accessor method so that other operations (like interrupt) can be performed. The name "flag" is not descriptive. – erickson Mar 23 '09 at 04:03
  • 2
    +1 doing while (!Thread.currentThread().isInteruppted()) is prefered – Toby Dec 23 '10 at 13:37
  • 2
    I don't get the "while" thing in the run method. Doesn't this mean that whatever is written in the run method will be being repeated? this is not something we wanted the thread to do in the first place :( –  Oct 28 '09 at 01:14
  • @Sofia, Yes. But, besides that, now we want to handle the while's condition, so that we can set it false whenever we want to. –  Jun 17 '10 at 20:52
  • 2
    Just as a side hint: A variable as flag only works, when the thread runs and it is not stuck. Thread.interrupt() should free the thread out of most waiting conditions (wait, sleep, network read, and so on). Therefore you should never never catch the InterruptedException to make this work. – ReneS Mar 23 '09 at 03:49
  • 2
    Both cases fail, when e.g you open an external process inside the while{// open ext process} and that process is hanged, now neither the thread will be interrupted nor it will reach the end to check on your Boolean condition, and you are left hanging... try it with e.g launch a python console using java.exec and try getting the control back without writing exit, and see if there is a way to kill that process and get out.... there is no way to get out of such situation... – Space Rocker Oct 04 '12 at 13:38
  • @karim79, do you know your solution is a memory hog when the same can be done in C++ exceptionally well and efficiently. – Space Rocker Oct 05 '12 at 09:04
13

I want to add several observations, based on the comments that have accumulated.

  1. Thread.stop() will stop a thread if the security manager allows it.
  2. Thread.stop() is dangerous. Having said that, if you are working in a JEE environment and you have no control over the code being called, it may be necessary; see Why is Thread.stop deprecated?
  3. You should never stop stop a container worker thread. If you want to run code that tends to hang, (carefully) start a new daemon thread and monitor it, killing if necessary.
  4. stop() creates a new ThreadDeathError error on the calling thread and then throws that error on the target thread. Therefore, the stack trace is generally worthless.
  5. In JRE 6, stop() checks with the security manager and then calls stop1() that calls stop0(). stop0() is native code.
  6. As of Java 13 Thread.stop() has not been removed (yet), but Thread.stop(Throwable) was removed in Java 11. (mailing list, JDK-8204243)
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
Steve11235
  • 2,849
  • 1
  • 17
  • 18
12

There is a way how you can do it. But if you had to use it, either you are a bad programmer or you are using a code written by bad programmers. So, you should think about stopping being a bad programmer or stopping using this bad code. This solution is only for situations when THERE IS NO OTHER WAY.

Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );
VadimPlatonov
  • 147
  • 1
  • 4
  • 2
    There are no reasons at all to do this, because it is still possible to call the public `Thread.stop` even if it is deprecated. – Lii Oct 04 '15 at 08:44
  • 1
    @Lii `Thread.stop` does the same but also checks access and permissions. Using `Thread.stop` is rather obvious, and I don't remember the reason why did I use `Thread.stop0` instead of that. Maybe `Thread.stop` didn't work for my special case (Weblogic on Java 6). Or maybe because `Thread.stop` is deprecated and causes warning. – VadimPlatonov Oct 07 '15 at 11:48
  • 1
    In my scenario this was the only way to stop a endless running thread. For some Reason .stop() did not stop the thread, but stop0() did – fiffy Jun 02 '17 at 08:30
8

I'd vote for Thread.stop().

As for instance you have a long lasting operation (like a network request). Supposedly you are waiting for a response, but it can take time and the user navigated to other UI. This waiting thread is now a) useless b) potential problem because when he will get result, it's completely useless and he will trigger callbacks that can lead to number of errors.

All of that and he can do response processing that could be CPU intense. And you, as a developer, cannot even stop it, because you can't throw if (Thread.currentThread().isInterrupted()) lines in all code.

So the inability to forcefully stop a thread it weird.

Anfet
  • 397
  • 4
  • 8
  • If the network operation is already safely abortable, just interrupt the thread. If the network operation is not safely abortable, you couldn't call `Thread.stop()` safely anyway. You are not voting for `Thread.stop()`, you are asking for every person who implements every operation that may take a long time to make it safely abortable. And that may well be a good idea, but it has nothing to do with implementing `Thread.stop()` as the way to request the safe abortion. We already have `interrupt` for that. – David Schwartz Aug 02 '16 at 10:49
  • 1
    *"So the inability to forcefully stop a thread it weird."* - ... until you look deeply (as the Java designers have done) and conclude that there are no technically viable solutions that aren't worse than deprecating `stop`. – Stephen C Feb 11 '20 at 23:45
5

The question is rather vague. If you meant “how do I write a program so that a thread stops running when I want it to”, then various other responses should be helpful. But if you meant “I have an emergency with a server I cannot restart right now and I just need a particular thread to die, come what may”, then you need an intervention tool to match monitoring tools like jstack.

For this purpose I created jkillthread. See its instructions for usage.

Jesse Glick
  • 24,539
  • 10
  • 90
  • 112
4

There is of course the case where you are running some kind of not-completely-trusted code. (I personally have this by allowing uploaded scripts to execute in my Java environment. Yes, there are security alarm bell ringing everywhere, but it's part of the application.) In this unfortunate instance you first of all are merely being hopeful by asking script writers to respect some kind of boolean run/don't-run signal. Your only decent fail safe is to call the stop method on the thread if, say, it runs longer than some timeout.

But, this is just "decent", and not absolute, because the code could catch the ThreadDeath error (or whatever exception you explicitly throw), and not rethrow it like a gentlemanly thread is supposed to do. So, the bottom line is AFAIA there is no absolute fail safe.

mlohbihler
  • 717
  • 1
  • 7
  • 15
  • AFAIK more and more services are becoming hybrid and use managed environment to execute 3rd party code (plugin, scripts, etc.) which they don't have fully control over the code, it seems unreasonable to completely take thread.stop off the table, since for service engineers, a live-and-serving state can be infinitely better than a non serving state (either due to hanging (which takes away threads), or busy infinite looping (which takes away cores)) – Weipeng Oct 25 '18 at 18:52
4

'Killing a thread' is not the right phrase to use. Here is one way we can implement graceful completion/exit of the thread on will:

Runnable which I used:

class TaskThread implements Runnable {

    boolean shouldStop;

    public TaskThread(boolean shouldStop) {
        this.shouldStop = shouldStop;
    }

    @Override
    public void run() {

        System.out.println("Thread has started");

        while (!shouldStop) {
            // do something
        }

        System.out.println("Thread has ended");

    }

    public void stop() {
        shouldStop = true;
    }

}

The triggering class:

public class ThreadStop {

    public static void main(String[] args) {

        System.out.println("Start");

        // Start the thread
        TaskThread task = new TaskThread(false);
        Thread t = new Thread(task);
        t.start();

        // Stop the thread
        task.stop();

        System.out.println("End");

    }

}
3

There is no way to gracefully kill a thread.

You can try to interrupt the thread, one commons strategy is to use a poison pill to message the thread to stop itself

public class CancelSupport {
    public static class CommandExecutor implements Runnable {
            private BlockingQueue<String> queue;
            public static final String POISON_PILL  = “stopnow”;
            public CommandExecutor(BlockingQueue<String> queue) {
                    this.queue=queue;
            }
            @Override
            public void run() {
                    boolean stop=false;
                    while(!stop) {
                            try {
                                    String command=queue.take();
                                    if(POISON_PILL.equals(command)) {
                                            stop=true;
                                    } else {
                                            // do command
                                            System.out.println(command);
                                    }
                            } catch (InterruptedException e) {
                                    stop=true;
                            }
                    }
                    System.out.println(“Stopping execution”);
            }

    }

}

BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);

http://anandsekar.github.io/cancel-support-for-threads/

Anand Rajasekar
  • 827
  • 8
  • 5
2

Generally you don't kill, stop, or interrupt a thread (or check wheter it is interrupted()), but let it terminate naturally.

It is simple. You can use any loop together with (volatile) boolean variable inside run() method to control thread's activity. You can also return from active thread to the main thread to stop it.

This way you gracefully kill a thread :) .

1

Attempts of abrupt thread termination are well-known bad programming practice and evidence of poor application design. All threads in the multithreaded application explicitly and implicitly share the same process state and forced to cooperate with each other to keep it consistent, otherwise your application will be prone to the bugs which will be really hard to diagnose. So, it is a responsibility of developer to provide an assurance of such consistency via careful and clear application design.

There are two main right solutions for the controlled threads terminations:

  • Use of the shared volatile flag
  • Use of the pair of Thread.interrupt() and Thread.interrupted() methods.

Good and detailed explanation of the issues related to the abrupt threads termination as well as examples of wrong and right solutions for the controlled threads termination can be found here:

https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads

ZarathustrA
  • 3,434
  • 32
  • 28
  • Since programs are no longer written by single developer, killing threads are often necessary. Therefore cannot be considered bad programming. I cannot imagine Linux without kill. Inability to kill threads is Java defect. – Pavel Niedoba Mar 07 '17 at 15:52
  • 1
    Awesome, Mr. Right... What if you have to call some 3rd party library, which you have no control over and which has a buggy timeout and might hang once every 1000-2000 times when being executed? Bad programming practice huh? Well you can't always have access to the code you are using. Anyway, the op is asking how to kill a thread not how to control its flow when designing his own code... – Arturas M May 08 '17 at 20:46
  • The question is what will happen when you kill a thread which has mutex owned or has some memory block allocated, or which should generate some event or data which other thread is waiting for? What will happen with the rest of the logic of your application? You will be always at risk that small and evident problem will be converted into complex problem which will be hard to reproduce and investigate. Killing the thread is unsafe because it can leave your application in a number of different inconsistent states. Take a look at the information from the link on cert.org. – ZarathustrA May 09 '17 at 08:07
  • We have a controlling thread that on certain conditions may decide that the whole calculation just became pointless. The many different runnables doing the actual work need to be splattered with some variant of isInterrupted() at any convenient place – how horrible! It is so much nicer if the controller causes a ThreadDeath to rise seemingly out of nowhere, cleanly unwinding all synchronized & finally blocks. Everyone says this is so error prone, but for fairly unrelated Threads, I don't see why. – Daniel Jan 17 '20 at 12:19
1

Here are a couple of good reads on the subject:

What Do You Do With InterruptedException?

Shutting down threads cleanly

splashout
  • 537
  • 5
  • 11
1

I didn't get the interrupt to work in Android, so I used this method, works perfectly:

boolean shouldCheckUpdates = true;

private void startupCheckForUpdatesEveryFewSeconds() {
    Thread t = new Thread(new CheckUpdates());
    t.start();
}

private class CheckUpdates implements Runnable{
    public void run() {
        while (shouldCheckUpdates){
            //Thread sleep 3 seconds
            System.out.println("Do your thing here");
        }
    }
}

 public void stop(){
        shouldCheckUpdates = false;
 }
Mindborg
  • 73
  • 3
  • 2
    volatile keyword should be added to shouldCheckUpdates, incase the compiler optimises with thread local storage. – clinux Apr 19 '18 at 05:26
0

Thread.stop is deprecated so how do we stop a thread in java ?

Always use interrupt method and future to request cancellation

  1. When the task responds to interrupt signal, for example, blocking queue take method.
Callable < String > callable = new Callable < String > () {
    @Override
    public String call() throws Exception {
        String result = "";
        try {
            //assume below take method is blocked as no work is produced.
            result = queue.take();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return result;
    }
};
Future future = executor.submit(callable);
try {
    String result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
    logger.error("Thread timedout!");
    return "";
} finally {
    //this will call interrupt on queue which will abort the operation.
    //if it completes before time out, it has no side effects
    future.cancel(true);
}

  1. When the task does not respond to interrupt signal.Suppose the task performs socket I/O which does not respond to interrupt signal and thus using above approach will not abort the task, future would time out but the cancel in finally block will have no effect, thread will keep on listening to socket. We can close the socket or call close method on connection if implemented by pool.
public interface CustomCallable < T > extends Callable < T > {
    void cancel();
    RunnableFuture < T > newTask();
}

public class CustomExecutorPool extends ThreadPoolExecutor {
    protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
        if (callable instanceof CancellableTask)
            return ((CancellableTask < T > ) callable).newTask();
        else
            return super.newTaskFor(callable);
    }
}

public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
    public synchronized void cancel() {
        try {
            obj.close();
        } catch (IOException e) {
            logger.error("io exception", e);
        }
    }

    public RunnableFuture < T > newTask() {
        return new FutureTask < T > (this) {
            public boolean cancel(boolean mayInterruptIfRunning) {
                try {
                    this.cancel();
                } finally {
                    return super.cancel(mayInterruptIfRunning);
                }
            }

        };
    }
}
Gautam Tadigoppula
  • 932
  • 11
  • 13
-3

After 15+ years of developing in Java there is one thing I want to say to the world.

Deprecating Thread.stop() and all the holy battle against its use is just another bad habit or design flaw unfortunately became a reality... (eg. want to talk about the Serializable interface?)

The battle is focusing on the fact that killing a thread can leave an object into an inconsistent state. And so? Welcome to multithread programming. You are a programmer, and you need to know what you are doing, and yes.. killing a thread can leave an object in inconsistent state. If you are worried about it use a flag and let the thread quit gracefully; but there are TONS of times where there is no reason to be worried.

But no.. if you type thread.stop() you're likely to be killed by all the people who looks/comments/uses your code. So you have to use a flag, call interrupt(), place if(!flag) all around your code because you're not looping at all, and finally pray that the 3rd-party library you're using to do your external call is written correctly and doesn't handle the InterruptException improperly.

Jack
  • 1,488
  • 11
  • 21