will java ExecutorService shutDown 方法可以保证所有的提交任务最终都会提交

will java ExecutorService shutDown method can ensure all submit task will finally submitted

正如 ExecutorService document 解释的那样 The shutdown() method will allow previously submitted tasks to execute before terminating。所以在我最初的理解中,当我们通过ctrl+c杀死线程时,所有提交的任务仍然会最终完成。但是实际结果好像不是。

executorService的生成如下:

CORE_POOL_SIZE = 1
return new ThreadPoolExecutor(CORE_POOL_SIZE, numConsumers,
                                  KEEP_ALIVE_TIME, TimeUnit.SECONDS,
                                  new LinkedBlockingQueue<>(),
                                  consumerThreadFactory);

在我的任务中,我将记录一些信息,任务代码示例如下:

log.info("before come into sleep.....")
try {
        Thread.sleep(sleepTime);
    } catch (InterruptedException e) {
        log.warn(" exception during sleep.....{}", request.getExecutionId());
        e.printStackTrace();
    }
 log.info("after come into sleep...")

我提交了几个任务,然后通过control+c终端线程,结果只有before come into sleep的日志是印刷品。

所以我不知道我的理解是否正确shutDown可以确保所有提交的任务最终完成。我也 google 一些类似的问题,但发现没有明确的答案。

Control+c 杀死整个 JVM

在控制台上按 Control+c 会终止整个 Java 进程 运行 您的线程。参见 Wikipedia

您正在打扰 JVM。这不是与您的Java应用交互的优雅方式。

所以,不,你不应该期望你的执行者服务继续 运行 提交的任务。你杀了它。

JVM 通常不设计为在启动后在控制台中进行操作。启动后,我所知道的与 JVM 交互的唯一两种方式是:

你说:

we kill thread through ctrl+c

不,ctrl+c 不会专门杀死一个线程。它会杀死你的整个 JVM。

awaitTermination

调用 ExecutorService#shutdown 后,如果您希望代码阻塞并等待所有提交的任务完成,请调用 ExecutorService#awaitTermination。如果任务仍然 运行.

,请指定在抛出异常之前等待的特定时间

这个等待终止是 shown in the JavaDoc 并且已经在 Stack Overflow 上的许多其他问题和答案中讨论过,有些是我写的。所以搜索以了解更多信息。

我相信从 ExecutorService (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown--) 的文档中可以清楚地看出它不会等待任务完成。为此,我们有 awaitTermination

This method does not wait for previously submitted tasks to complete execution. Use awaitTermination to do that.

本文档的 Usage Example 部分也提供了如何实现此目的的清晰示例。

为什么 awaitTermination 在正常关机期间很重要? 使用 shutdown() 就像通知您打算停止由 ExecutorService 管理的所有线程。这里不涉及阻塞。您的主线程将恢复执行并在 shutdown() 之后继续执行后续代码。在处理 JVM (https://docs.oracle.com/javase/8/docs/technotes/guides/lang/hook-design.html) 的正常关闭时,将调用一个单独的线程以期望它完成其任务,当它完成时,JVM 将关闭。如果需要等待任务完成,block shutdown hook thread using awaitTermination().