如何有效地重置线程池

时间:2013-04-20 21:53:22

标签: java concurrency threadpool

我正在使用线程池来启用多个不重要的任务排队和(可能)执行但是我需要能够轻松取消所有排队和执行的任务并从头开始新的队列。

即:

// startup
pool = Executors.newFixedThreadPool(5);

// reset
pool.shutdownNow();
pool = Executors.newFixedThreadPool(5);

我现在使用的实现似乎工作但我不确定完全关闭并创建新的线程池特别有效。

重置会定期发生,在某些用法中,它会像安排任务一样经常发生!既然没有办法确定是否有任何任务正在等待执行(或者在那里?)我觉得我经常关闭游泳池。

是否有更合适的池实现或更好的方法来实现此功能?

编辑:解决方案

我现在正在运行:

// startup
pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);

// reset
for (Future<?> task : pool.getQueue().toArray(new Future[0]))
    task.cancel(true);

我忽略了对'purge'的调用,因为这很慢,无论如何队列都会被池整理。我知道当前执行的任务可能不会被此终止,这对我有用。

感谢。

2 个答案:

答案 0 :(得分:0)

您可以监控从提交任务中获得的所有Future以及cancel()所有这些,这将允许您重新使用线程池而无需重新创建。但是,我怀疑你会获得太多额外的效率。

只要您不经常这样做,我认为您的机制应该可以正常工作。有一点需要注意的是,虽然你正在调用pool.shutdownNow(),但这只会中断正在运行的作业,这些作业不一定会阻止它们。这取决于它们正在做什么以及它们是否正在执行经常抛出InterruptedException或者正在侦听线程中断标志的方法。因此,即使shutdownNow()返回,某些任务仍可能正在执行。

答案 1 :(得分:-2)

您可以取消所有待处理(和可能正在运行)的任务:

for (Future f: pool.getQueue().toArray(new Future[0]))
{
    f.cancel(true); // or false
}
pool.purge();