删除 ThreadPoolExecutor 的所有排队任务

我有一个关于ThreadPoolExecutor的相当简单的问题。我有以下情况:我必须使用队列中的对象,为它们创建适当的工作线程任务,并将它们提交给ThreadPoolExecutor。这很简单。但在关闭方案中,许多工作线程可能排队等待执行。由于其中一个任务可能运行了一个小时,并且我想要相对快速地优雅地关闭应用程序,因此我想从ThreadPoolExecutor中丢弃所有排队的任务,而已经处理的任务应该正常完成。

ThreadPoolExecutor 文档有一个 remove() 方法,但只允许删除特定的任务。purge() 仅适用于已取消的未来任务。我的想法是清除包含所有排队任务的队列。ThreadPoolExecutor 提供对此内部队列的访问,但文档指出:

方法 getQueue() 允许访问工作队列以进行监视和调试。强烈建议不要将此方法用于任何其他目的。

因此,抓住这个队列并清除它不是一种选择。此外,文档的这个片段说:

提供了两种方法,remove(java.lang.Runnable) 和 purge() 可用于在大量排队任务被取消时帮助回收存储空间。

如何?当然,我可以维护我提交给执行器的所有任务的列表,并且在关闭的情况下,我迭代所有条目并使用movection()方法从ThreadPoolExecutor中删除它们...但。。。来吧,这是浪费内存,维护此列表很麻烦。(例如,删除已执行的任务)

我感谢任何提示或解决方案!


答案 1

我曾经在具有长运行线程的应用程序上工作。我们在关机时这样做,

BlockingQueue<Runnable> queue = threadPool.getQueue();
List<Runnable> list = new ArrayList<Runnable>();
int tasks = queue.drainTo(list);

该列表将保存到文件中。启动时,该列表将添加回池中,因此我们不会丢失任何作业。


答案 2

您是否考虑过包装执行器服务?创建一个

CleanShutdownExecutorService implements Executor 

将所有调用委托给另一个执行者,但将期货保留在自己的列表中。然后,CleanShutdownExecutorService可以有一个 cancelRemainingTasks() 方法调用 shutdown(),然后对其列表中的所有 Futures 调用 cancel(false)。