Executor Service 的 shutdown 和 shutdownNow 的区别

问题描述 投票:0回答:3

我想知道关闭

shutdown()
shutdownNow()
之间的基本区别?

据我了解:

Executor Service

应用于

graceful
关闭,这意味着所有正在运行并排队等待处理但尚未启动的任务都应该被允许完成

shutdown()

会“突然”关闭,这意味着一些未完成的任务被取消,未启动的任务也被取消。还有什么我遗漏的隐式/显式的吗?


P.S:我发现了另一个与此相关的问题“如何关闭执行程序服务”,但不完全是我想知道的。

总而言之,你可以这样想:

java java.util.concurrent
3个回答
162
投票
只会告诉执行器服务它不能接受新任务,但已经提交的任务继续运行

    shutdown()
  • 将执行相同的操作,并且将通过中断相关线程来
    尝试取消
    已提交的任务。请注意,如果您的任务忽略中断,
  • shutdownNow()
  • 的行为方式将与
    shutdownNow
    完全相同。
    您可以尝试下面的示例,并将 
    shutdown
     替换为 
    shutdown
  • ,以更好地理解不同的执行路径:

使用
shutdownNow
,输出为
shutdown

,因为正在运行的任务
    没有
  • 中断并继续运行。
    使用 
    Still waiting after 100ms: calling System.exit(0)...
    ,输出为 shutdownNow
  • interrupted
  • ,因为正在运行的任务被中断,捕获中断,然后停止正在执行的操作(打破 while 循环)。
    使用 
    Exiting normally...
    ,如果您注释掉 while 循环中的行,您将得到
    shutdownNow
    ,因为正在运行的任务不再处理中断。
  • 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...");
}

11
投票
    要终止 ExecutorService 内的线程,您可以调用其
  • shutdown()
     方法。 ExecutorService不会立即关闭,但它不会再接受新任务,一旦所有线程完成当前任务,ExecutorService就会关闭。在调用 shutdown() 之前提交给 ExecutorService 的所有任务都会被执行。

shutdown()

    如果想立即关闭ExecutorService,可以调用
  • shutdownNow()
    方法。这将尝试立即停止所有正在执行的任务,并跳过所有已提交但未处理的任务。对于正在执行的任务不提供任何保证。也许他们会停下来,也许会执行到最后。这是尽最大努力的尝试。

来自

javadocs


2
投票

shutdownNow()

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

void shutdown

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

除了尽最大努力阻止之外,没有任何保证


  积极处理

执行任务。

例如,典型的实现将通过取消 Thread.interrupt(),因此任何无法响应中断的任务 可能永远不会终止。 返回:从未开始执行的任务列表

© www.soinside.com 2019 - 2024. All rights reserved.