如何在Java中杀死Java .lang. thread ?


当前回答

一种方法是设置一个类变量并将其用作哨兵。

Class Outer {
    public static volatile flag = true;

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

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

}

设置一个外部类变量,如上面例子中的flag = true。将其设置为false以“杀死”线程。

其他回答

在Java中,线程不会被杀死,但是线程的停止是通过协作的方式完成的。线程被要求终止,然后线程可以优雅地关闭。

通常使用一个易失性布尔字段,线程定期检查,并在设置为相应值时终止。

我不会使用布尔值来检查线程是否应该终止。如果你使用volatile作为字段修饰符,这将可靠地工作,但如果你的代码变得更复杂,而不是在while循环中使用其他阻塞方法,它可能会发生,你的代码根本不会终止,或者至少需要更长的时间。

某些块库方法支持中断。

每个线程已经有一个布尔标志中断状态,你应该利用它。它可以这样实现:

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

public void cancel() { interrupt(); }

源代码改编自Java并发实践。因为cancel()方法是公共的,你可以让另一个线程按你的意愿调用这个方法。

我想根据所积累的意见补充几点看法。

Thread.stop() will stop a thread if the security manager allows it. 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? 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. 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. In JRE 6, stop() checks with the security manager and then calls stop1() that calls stop0(). stop0() is native code. As of Java 13 Thread.stop() has not been removed (yet), but Thread.stop(Throwable) was removed in Java 11. (mailing list, JDK-8204243)

没有办法优雅地终止线程。

您可以尝试中断线程,一个常用的策略是使用毒丸来通知线程停止自己

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/

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.

但是,这只是“体面的”,而不是绝对的,因为代码可以捕获ThreadDeath错误(或您显式抛出的任何异常),而不是像一个绅士线程应该做的那样重新抛出它。所以,AFAIA的底线是没有绝对的故障保险。

这个问题相当模糊。如果你的意思是“我如何编写一个程序,使线程在我希望它停止运行时停止运行”,那么各种其他回答应该是有帮助的。但是,如果您的意思是“我有一个服务器紧急情况,我现在不能重新启动,我只是需要一个特定的线程终止,无论发生什么”,那么您需要一个干预工具来匹配jstack等监视工具。

为此,我创建了jkillthread。请参阅其使用说明。