ExecutorService - 如何以非阻塞样式等待所有任务的完成

时间:2015-06-12 14:24:13

标签: java multithreading web-applications executorservice

我在 Java Web服务器应用程序中使用ExecutorService以并行方式执行某些计算任务,然后使用shutdown()调用awaitTermination()以等待所有任务要完成。整个计算有时可能需要几十分钟。

事情是awaitTermination()方法阻止主线程直到超时(或中断)但我只想启动任务并立即响应到客户端并且在所有任务竞争之后关闭服务(以下约定以始终关闭线程池)。

所以我的问题是,有什么方法可以在完成所有任务时通知,以便我可以调用shutdown()方法吗?倾听者或其他东西..

谢谢!

2 个答案:

答案 0 :(得分:5)

您正在尝试解决不存在的问题。考虑documentation of ExecutorService.shutdown()

  

启动有序关闭,其中先前提交的任务已执行,但不会接受任何新任务。 ...

     

此方法不会等待先前提交的任务完成执行。

换句话说,只是调用The email field is required.已经完成了你想要的一切

  • 完成之前提交的所有任务
  • 启动关机
  • 它不等待

唯一的障碍是你正在调用shutdown(),尽管你不想等待,这有一个简单的解决方案:不要打电话 awaitTermination

出现混乱是因为在你的问题中你问“我在完成所有任务时如何得到通知,所以我可以调用awaitTermination方法”,但这与你在代码中实际做的事情相矛盾。您在 shutdown()之后拨打了awaitTermination ,因此您没有等待启动关机,而是首先启动shutDown并等待其完成,是shutdown的目的,等待完成关闭

要把它放在一个句子中,只需在提交后调用awaitTermination,以便在完成所有提交的作业后关闭服务,除非你真的想等待终止,否则不要调用shutDown

答案 1 :(得分:0)

感谢VGR的评论,我解决了创建另一个Thread的问题,其中我将现有代码包装成这样:

Thread thread = new Thread(() -> {
    ExecutorService service = Executors.newCachedThreadPool();

    collection.forEach(item -> service.submit(() -> {
            // some computational work
        });

    try {
        service.shutdown()
        service.awaitTermination(2, TimeUnit.HOURS);
    catch (InterruptedException iEx) {
        // handle exception
    }
});

thread.start();

return ResponseToClient();