简体   繁体   中英

How can I immediately terminate a Thread? (Not interrupt)

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. (Eg, 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:

  1. ExecutorService.shutdown()
  2. Future.cancel()
  3. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM