【发布时间】:2013-12-18 02:32:34
【问题描述】:
工作线程发出正常关闭信号的最佳方式是什么?
我有一个固定大小的线程池,它通过一组连续的任务工作,每个任务持续不超过几秒钟。在正常操作期间,它运行良好,并且随着工作量的增加而突飞猛进。
我遇到的问题是在其中一个线程中引发异常时。如果发生这种情况,我想把整个事情搞砸,但一直无法正常工作。
目前的做法
我一直在使用的天真的方法是在“Supervisor”类中有一个静态方法,它使用标准的shutdown() 和awaitTermination() 方法关闭线程池。如果遇到问题,任何“Worker”类都会调用它。这样做不是传播异常,因为execute() 需要Runnable 并且run() 方法不能抛出异常。
这是一些伪代码:
// Finds work to do and passes them on to workers
class Supervisor {
ThreadPoolExecutor exec;
static main() {
exec = new FixedThreadPool(...);
forever {
exec.execute(new Worker(next available task));
}
}
static stopThreadPool() {
exec.shutdown();
if(!exec.awaitTermination(timeout_value)) {
print "Timed out waiting on terminate"
}
}
}
class Worker {
run() {
try {
// Work goes here
} catch () {
Supervisor.stopThreadPool()
}
}
}
我看到的效果是线程确实暂停了一段时间,但随后我看到了超时消息,它们都恢复了处理。这种模式一直持续到我手动关闭它。如果我在跳出循环后在 main 方法中调用stopThreadPool(),则关机会按预期正确发生。
这种方法显然是错误的,因为它不起作用,但它也感觉设计不正确。
重申这个问题:工作线程发出正常关闭信号的最佳方式是什么?
其他信息
我在 SO 上看到的问题有两种:
- “如何杀死线程池中的线程?”
- “我如何知道我的所有线程都已完成?”
那不是我想要的。他们似乎也只谈论一组有限的任务,而我正在处理连续的提要。
我已经阅读了一种使用exec.submit() 和Futures 的替代方法,它让主管类有责任检查一切是否正常,但我对它的了解还不够,无法知道它是否是一个更好的设计。例外情况是,嗯......例外,所以我不想在正常情况下不必要地增加工作/复杂性。
(小注:这是一个工作项目,还有其他人参与。为简单起见,我在问题中说“我”。)
【问题讨论】:
-
您应该对
awaitTermination的返回值进行操作 - 如果在超时内终止没有完成,它会返回false。你也可以考虑shutdownNow -
@OldCurmudgeon 我已经这样做了。我在伪代码中找到了它,并在问题中提到了它。
-
@dbw SO = 堆栈溢出
-
Runnable可以抛出异常,只是未检查的。这很容易解决。 -
shutDownNow也是一个优雅的关闭请求,您应该使用它。
标签: java multithreading threadpoolexecutor