Executor Service的shutdown和shutdownNow之间的区别

时间:2012-07-17 10:02:09

标签: java java.util.concurrent

我想了解shutdown()shutdownNow()关闭Executor Service的基本区别?据我所知shutdown()应该用于优雅关闭这意味着应该允许所有正在运行并排队等待处理但未启动的任务完成,shutdownNow()执行突然关闭意味着某些未完成的任务被取消并且未启动的任务也被取消。我还缺少其他隐含/明确的东西吗?

P.S:我发现SO的另一个问题与此相关,但不完全是我想知道的。

3 个答案:

答案 0 :(得分:108)

总之,你可以这样想:

  • shutdown()只会告诉执行程序服务它不能接受新任务,但已经提交的任务继续运行
  • shutdownNow()将执行相同操作并尝试通过中断相关线程来取消已提交的任务。请注意,如果您的任务忽略了中断,shutdownNow的行为方式与shutdown完全相同。

您可以尝试以下示例,并将shutdown替换为shutdownNow,以便更好地了解不同的执行路径:

  • shutdown,输出为Still waiting after 100ms: calling System.exit(0)...,因为正在运行的任务中断并继续运行。
  • shutdownNow,输出为interruptedExiting normally...,因为正在运行的任务被中断,捕获中断然后停止它正在做的事情(打破while循环)。
  • 使用shutdownNow,如果您在while循环中注释掉行,则会得到Still waiting after 100ms: calling System.exit(0)...,因为正在运行的任务不再处理中断。
public static void main(String[] args) throws InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(1);
    executor.submit(new Runnable() {

        @Override
        public void run() {
            while (true) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("interrupted");
                    break;
                }
            }
        }
    });

    executor.shutdown();
    if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS)) {
        System.out.println("Still waiting after 100ms: calling System.exit(0)...");
        System.exit(0);
    }
    System.out.println("Exiting normally...");
}

答案 1 :(得分:3)

  • shutdown()

要终止ExecutorService中的线程,请调用其shutdown()方法。 ExecutorService不会立即关闭,但它将不再接受新任务,并且一旦所有线程完成当前任务,ExecutorService就会关闭。调用shutdown()之前提交给ExecutorService的所有任务都将被执行。

  • shutdownNow()

如果要立即关闭ExecutorService,可以调用shutdownNow()方法。这将尝试立即停止所有正在执行的任务,并跳过所有已提交但未处理的任务。没有关于执行任务的保证。也许他们会停止,也许是执行直到结束。这是一次尽力而为的尝试。

答案 2 :(得分:2)

来自javadocs

  

void shutdown

     

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

     

List<Runnable> shutdownNow()

     

尝试停止所有正在执行的任务,停止处理   等待任务,并返回正在等待的任务列表   执行。

     

除了尽力停止尝试之外没有任何保证   积极处理 执行任务。

     

例如,典型的实现将取消via   Thread.interrupt(),所以任何无法响应中断的任务   可能永远不会终止。

     

返回:从未开始执行的任务列表