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

时间:2012-10-29 10:49:59

标签: java multithreading thread-safety threadpool

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

通常我会尝试:

        while(!Thread.currentThread().isInterrupted()) {...

关闭while循环...

但我有一个仅包含

的线程
        while(!Thread.currentThread().isInterrupted()) {//which is true

这就是我关闭线程的方式:

pool.shutdownNow();

那你怎么关闭这样一个线程?

4 个答案:

答案 0 :(得分:15)

您可以添加volatile布尔flag

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();

<强>更新

来自shutdownNow()

的Java文档
  

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

     

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

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

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

答案 1 :(得分:2)

而不是你可以使用自己创建的标志作为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();

这将使代码正常完成。

答案 2 :(得分:2)

如果你按照你的描述实现了它,它应该可以正常工作。

当你调用pool.shutdownNow()时,它应该中断当前活动的所有工作线程。假设应用程序特定的run()方法检查中断标志并在找到它时自行终止,那么您的线程应该关闭。

确实没有必要使用 ad hoc 取消标记添加不同的机制......或者其他一些机制。


顺便提一下,interrupt()优于 ad hoc 取消的原因有几个:

  • 像ExecutorService这样的标准API使用它。
  • 各种低级API方法,例如sleepwaitjoin和一些I / O方法对它们都很敏感。

答案 3 :(得分:1)

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

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