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

ExecutorService - How to wait for completition of all tasks in non-blocking style

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

事情是 awaitTermination() 方法阻塞主线程直到超时(或 中断 ),但我只想开始任务并 立即响应 客户端并在所有任务竞争后关闭服务(遵循始终关闭线程池的约定)。

所以我的问题是,有没有什么方法可以让我在所有任务完成后得到通知,这样我就可以调用shutdown() 方法?听众什么的..

谢谢!

感谢 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();

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

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. …

This method does not wait for previously submitted tasks to complete execution.

换句话说,只需调用 shutdown() 就可以满足您的所有需求

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

唯一的障碍是尽管您不想等待,但您仍在调用 awaitTermination,这有一个简单的解决方案:不要调用 awaitTermination.

之所以会产生混淆,是因为在您的问题中您问的是“当所有任务完成后如何通知我,以便我可以调用 shutdown() 方法”,但这与您实际在做的事情相矛盾代码。您正在调用 awaitTermination after shutDown 所以您不是在等待启动关机,而是先启动 shutdown 并等待其完成然后,就是awaitTermination的目的,等待关机完成


一言以蔽之,提交后调用shutDown,以便在所有提交的作业完成后关闭服务,除非你真的想等待,否则不要调用awaitTermination终止。