Java 如何杀死有一段时间的线程(true)?

Java 如何杀死有一段时间的线程(true)?,java,multithreading,thread-safety,threadpool,Java,Multithreading,Thread Safety,Threadpool,我正在尝试关闭线程池中的所有线程 通常我会尝试: while(!Thread.currentThread().isInterrupted()) {... 要关闭while循环 但是我有一条线,它只包括 while(!Thread.currentThread().isInterrupted()) {//which is true 以下是我关闭线程的方式: pool.shutdownNow(); 那么您将如何关闭这样一个线程呢?您可以使用自建的标志作为while

我正在尝试关闭线程池中的所有线程

通常我会尝试:

        while(!Thread.currentThread().isInterrupted()) {...
要关闭while循环

但是我有一条线,它只包括

        while(!Thread.currentThread().isInterrupted()) {//which is true
以下是我关闭线程的方式:

pool.shutdownNow();

那么您将如何关闭这样一个线程呢?

您可以使用自建的标志作为while循环的条件

public class MyClass implements Runnable
{

    private volatile boolean running = true;

    public void stopRunning()
    {
        running = false;
    }

    public void run()
    {
        while (running)
        {

        }
        // shutdown stuff here
    }

}
现在,要停止它,只需拨打:

myClassObject.stopRunning();

这将使代码正常完成。

您可以添加一个
volatile
布尔
标志

public class Worker implements Runnable {

    volatile boolean cancel = false;
    @Override
    public void run() {

        while (!cancel) {
            // Do Something here
        }
    }

    public void cancel() {
        cancel = true;
    }
}
现在你可以打电话了

worker.cancel();
更新:

来自

尝试停止所有正在执行的任务,停止正在等待的任务的处理,并返回正在等待执行的任务的列表

除了尽最大努力停止处理积极执行的任务之外,这里没有任何保证。例如,典型的实现将通过Thread.interrupt()取消,因此无法响应中断的任何任务可能永远不会终止

因此,您必须通过保留中断来定义中断策略

  catch (InterruptedException ie) {
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }

如果您使用的是
java.util.concurrent
ExecutorService实现,那么它肯定会向其线程池中的所有线程发送
中断
信号。您的rogue任务的问题可能是循环实际上并没有迭代,而是在循环中的某个位置阻塞,因此
interrupted
状态根本没有得到检查


您可能还有另一个问题:while循环运行一些代码,捕获InterruptedException,而没有正确处理它,有效地吞咽中断信号。这是一个常见的编码错误,在大多数情况下是由于检查了
InterruptedException
这一丑陋事实造成的。

如果您已经按照所述实现了这一点,它应该可以正常工作

调用pool.shutdownNow()
时,应该中断当前处于活动状态的所有工作线程。假设特定于应用程序的
run()
方法检查中断标志,并在发现该标志已设置时自行终止,则线程应该关闭

真的没有必要使用临时取消标志添加不同的机制。。。或者类似的


顺便提一下,
interrupt()
优于临时取消的原因有两个:

  • 像ExecutorService这样的标准API使用它
  • 各种低级API方法,如
    sleep
    wait
    join
    和一些I/O方法对它很敏感

您需要知道该线程的退出条件……当您的类的方法中有上述while循环,并且
扩展了thread
,您可以使用
this.isInterrupted()
而不是
thread.currentThread().isInterrupted())
@Philipp希望OP不会扩展
线程
@Philipp这是一种广泛接受的最佳实践。只需在谷歌上搜索“java扩展线程”就可以找到它的全部内容。这些教程显然是在伤害读者。@Philipp官方文档不是为了推荐,而是为了。。。那么文件,,在这种情况下,事实上有两种方法可以为
线程
实例提供入口点。-1这是多余的-为什么不只使用中断机制?@AmitD您确实需要其中的否定:)@MarkoTopolnik他有一个线程的中断状态为false,因此如果存在否定,它将永远不会进入。我认为措辞上有差异。@AmitD没有听你的。(中断==假)=>(!中断真),因此条件始终为真。OP肯定不会因为循环从未被输入而受到影响,而是因为无法打破循环。在我看来,第一行建议是“检查它被吞没的地方”,并且只有在最后的解决方法中才使用自定义机制,因为这涉及到更多的代码,为代码失败带来了新的方式。@assylias Heh Heh,不仅仅是今天:)