java—删除threadpoolexecutor的所有排队任务

jrcvhitl  于 2021-06-30  发布在  Java
关注(0)|答案(10)|浏览(831)

关于threadpoolexecutor,我有一个相当简单的问题。我有以下情况:我必须使用队列中的对象,为它们创建适当的辅助任务,并将它们提交给threadpoolexecutor。这很简单。但在关闭场景中,许多工作人员可能排队等待执行。由于其中一个任务可能要运行一个小时,并且我希望应用程序能够相对快速地正常关闭,因此我希望放弃threadpoolexecutor中所有排队的任务,而已经在处理的任务应该正常完成。
threadpoolexecutor文档有一个remove()方法,但只允许删除特定的任务。purge()只适用于已取消的未来任务。我的想法是清除包含所有排队任务的队列。threadpoolexecutor提供对此内部队列的访问,但文档说明:
方法getqueue()允许访问工作队列以进行监视和调试。强烈反对将此方法用于任何其他目的。
所以抓取这个队列并清除它不是一个选择。此外,这段文档还说:
提供的两个方法remove(java.lang.runnable)和purge()可用于在取消大量排队任务时帮助进行存储回收。
怎样?当然,我可以维护一个我提交给执行器的所有任务的列表,在关机的情况下,我迭代所有条目,并使用remove()方法将它们从threadpoolexecutor中删除。。。但是。。。拜托,这是在浪费内存,维护这个列表也很麻烦(删除已执行的任务(例如)
我感谢任何提示或解决方案!

83qze16e

83qze16e1#

awaitTermination(long timeout, TimeUnit unit) 关机后工作?
executor.shutdown();执行器。等待终止(60,时间单位。秒)

a64a0gku

a64a0gku2#

你考虑过打包服务吗?创建

CleanShutdownExecutorService implements Executor

它将所有调用委托给另一个执行者,但将未来保留在自己的列表中。cleanshutdownexecutorservice可以有一个cancelremainingtasks()方法,该方法调用shutdown(),然后对其列表中的所有未来调用cancel(false)。

myzjeezk

myzjeezk3#

由于executorservice.shutdown()做得不够,executorservice.shutdownnow()做得太多,我想你必须在中间写一些东西:记住所有提交的任务,并在调用之后(或之前)手动删除它们 shutdown() .

disbfnqx

disbfnqx4#

您可以创建自己的任务队列并将其传递给 ThreadPoolExecutor 施工单位:

int poolSize = 1; // number of threads
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>();
Executor executor = new ThreadPoolExecutor(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS, queue);

当您清除代码中某个地方的队列时,剩余的任务将不会执行:

queue.clear();
woobm2wo

woobm2wo5#

你可以试试 allowCoreThreadTimeOut(true);

93ze6v8z

93ze6v8z6#

bombe的答案正是你想要的。 shutdownNow() 停止一切使用核弹和铺路方法。除了子类化 ThreadPoolExecutor 你正在使用的。

tuwxkamq

tuwxkamq7#

告诉线程池shutdown,getqueue,对于每个runnable,使用remove方法删除每个runnable。根据队列的类型,可以根据返回值提前停止删除。
基本上,这就是抓取队列并清除它,只通过有效的方法进行清除。不是手动记住所有提交,而是使用线程池已经记住所有提交的事实。但是,您可能需要为队列创建一个防御性副本,因为我认为它是一个实时视图,因此如果您在实时视图上迭代/进行eaching,删除可能会导致并发修改异常。

7lrncoxx

7lrncoxx8#

这是一个老问题,但如果这有助于其他人:您可以在调用shutdown()时设置一个volatile boolean,如果在真正开始之前设置了该boolean,则可以终止每个提交的任务。这将允许真正开始完成的任务,但会阻止排队的任务开始其实际活动。

kd3sttzy

kd3sttzy9#

一个疯狂和不干净的解决方案可能会奏效(不是真正的思考或测试)将覆盖 interrupt() 只有在设置了某个全局值的情况下,才会拒绝在 interrupt() 由shutdownnow()调用。
这样你就可以使用 shutdownNow() 不?

kjthegm6

kjthegm610#

我以前在一个长线程的应用程序上工作。我们在关机的时候做这个,

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

列表将保存到文件中。在启动时,列表会被添加回池中,这样我们就不会失去任何工作。

相关问题