执行器服务关机与关机的区别

我想知道 shutdown()shutdownNow()关闭 Executor Service的基本区别是什么?

据我所知:

shutdown()应该用于 优雅关闭,这意味着所有正在运行和排队等待处理但未启动的任务都应该允许完成

shutdownNow()执行 突然关闭,这意味着一些未完成的任务被取消,未启动的任务也被取消。我还漏掉了什么含蓄或明确的东西吗?

附注: 我在 如何关闭执行器服务上发现了另一个与此相关的问题,但并不完全是我想知道的。

60404 次浏览

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

  • 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...");
}

来自 Javadocs:

void shutdown

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

List<Runnable> shutdownNow()

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

除了尽最大努力去阻止之外,没有任何保证 主动处理执行任务。

例如,典型的实现将通过 中断() ,因此任何无法响应中断的任务 可能永远不会终止。

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

  • 返回文章页面

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

  • 返回文章页面

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