删除ThreadPoolExecutor的所有排队任务

Mal*_*lax 26 java multithreading executorservice executor threadpool

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

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

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

所以抓住这个队列并清除它不是一个选择.此外,该文档的片段说:

当大量排队的任务被取消时,两个提供的方法remove(java.lang.Runnable)和purge()可用于协助存储回收.

怎么样?当然,我可以维护我提交给执行程序的所有任务的列表,在关闭的情况下,我遍历所有条目并使用remove()方法将它们从ThreadPoolExecutor中删除......但是...来吧,这是一个浪费记忆力和维护这份清单的麻烦.(例如,删除已执行的任务)

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

ZZ *_*der 13

我曾经在使用长线程的应用程序上工作.我们在关机时这样做

BlockingQueue<Runnable> queue = threadPool.getQueue();
List<Runnable> list = new ArrayList<Runnable>();
int tasks = queue.drainTo(list);
Run Code Online (Sandbox Code Playgroud)

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

  • 我的问题很好.:-)我的情况持久性任务不是问题.但是你的补充可能有助于其他人,谢谢!:) (2认同)

Sbo*_*odd 10

你考虑过包装ExecutorService吗?创建一个

CleanShutdownExecutorService implements Executor 
Run Code Online (Sandbox Code Playgroud)

将所有调用委托给另一个Executor,但将Futures保留在自己的列表中.然后,CleanShutdownExecutorService可以使用cancelRemainingTasks()方法调用shutdown(),然后在其列表中的所有Futures上调用cancel(false).


Bom*_*mbe 5

由于ExecutorService.shutdown()做得不够,而ExecutorService.shutdownNow()做得太多,我猜你必须在中间写一些东西:记住所有提交的任务并在调用shutdown().


RTS*_*lio 5

这是一个老问题,但以防万一这对其他人有帮助:您可以在调用 shutdown() 时设置一个易失性布尔值,并且如果在真正开始之前设置了该布尔值,则让每个提交的任务终止。这将允许真正开始完成的任务,但会阻止排队任务开始其实际活动。