Executor Service的shutdown和shutdownNow之间的区别

Gee*_*eek 64 java java.util.concurrent

我想知道的基本区别shutdown(),并shutdownNow()为关闭Executor Service?据我了解shutdown()应该用于优美关机,这意味着人乳宁,并排队等待处理,但尚未开始应该可以完成所有任务,并shutdownNow()做一个突然关机意味着一些未完成的任务被取消,未启动的任务也被取消.我还缺少哪些隐含/明确的东西?

PS:我发现了另一个问题,关于SO与此相关的,但不是我想知道到底是什么.

ass*_*ias 116

总之,你可以这样想:

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

你可以试试下面的例子中,更换shutdownshutdownNow更好地理解执行的不同的路径:

  • with 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...");
}
Run Code Online (Sandbox Code Playgroud)

  • 为了增加困惑,在doc API中它表示shutdown()`这个方法不等待先前提交的任务完成执行.使用awaitTermination来做到这一点.它说**不等待**这与这个答案相反. (8认同)
  • 是的 - 您无法强制线程在Java中终止. (5认同)
  • @supertonsky"*它不等待*",在该上下文中,意味着调用shutdown会立即返回,而不会阻塞(`awaitTermination`会阻塞).但它允许先前提交的任务完成他们正在做的事情. (4认同)
  • @MarounMaroun线程中断时,其中断标志设置为true.但就是这样,中断不会阻止线程(并且它也不会中断).因此,您需要定期检查中断标志,并在捕获它时正常退出(通常通过退出,如示例中所示,或通过抛出InterruptedException).在示例中,当条件被删除时,您需要使用System.exit(0)强制终止程序,否则它将无限期地继续运行. (4认同)
  • 是/否:关闭不会取消等待任务,它只会阻止提交新任务.但是,一旦线程可用,就会运行已提交的任务. (3认同)

Ahm*_*OUR 6

  • shutdown()

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

  • shutdownNow()

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