Executor服务的shutdown和shutdownNow之间的区别

我想知道shutdown()shutdownNow()关于Executor Service的基本区别吗?就我所知, shutdown()应该用于正常closures,这意味着所有正在运行并排队等待处理但未启动的任务应该被允许完成并shutdownNow()做一个突然的closures意味着一些未完成的任务被取消,未开始的任务也被取消。 还有什么是隐含的/明确的,我失踪了?

PS:我发现了与此有关的另一个问题,但不完全是我想知道的。

总之,你可以这样想:

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

您可以尝试下面的示例,并通过shutdownNowreplaceshutdownNow以更好地理解不同的执行path:

  • shutdown ,输出Still waiting after 100ms: calling System.exit(0)...因为正在运行的任务没有中断并继续运行。
  • shutdownNow ,输出interruptedExiting normally...因为正在运行的任务被中断,捕获中断,然后停止它正在做什么(打破了while循环)。
  • 使用shutdownNow ,如果注释掉while循环中的行, Still waiting after 100ms: calling System.exit(0)...仍会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

启动先前提交的任务被执行的有序closures,但不接受新的任务。

List<Runnable> shutdownNow()

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

尽力而为的尝试停止处理主动执行的任务是没有保证的

例如,典型的实现将通过Thread.interrupt()取消,所以任何不能响应中断的任务都不会终止。

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

  • shutdown()

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

  • shutdownNow()

如果你想立即closuresExecutorService,你可以调用shutdownNow()方法。 这将尝试立即停止所有执行的任务,并跳过所有提交但未处理的任务。 对执行任务没有保证。 也许他们停下来,也许是执行到最后。 这是一个尽最大努力的尝试。