我正在尝试关闭我的线程池中的所有线程。
通常我会尝试:
while(!Thread.currentThread().isInterrupted()) {...
关闭while循环...
但我有一个仅包含
的线程 while(!Thread.currentThread().isInterrupted()) {//which is true
这就是我关闭线程的方式:
pool.shutdownNow();
那你怎么关闭这样一个线程?
答案 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();
<强>更新强>
的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 取消的原因有几个:
sleep
,wait
,join
和一些I / O方法对它们都很敏感。答案 3 :(得分:1)
如果您正在使用java.util.concurrent
ExecutorService实现,那么它肯定会向其线程池中的所有线程发送interrupt
信号。你的流氓任务的问题可能是循环实际上没有迭代,而是阻塞在某个地方,所以interrupted
状态根本没有得到检查。
你可能遇到的另一个问题是:while循环运行一些代码捕获InterruptedException 而不正确处理它,有效地吞下中断信号。这是一个常见的编码错误,并且在大多数情况下是由于检查InterruptedException
的丑陋事实。