shutdown和awaitTermination哪个第一次调用有什么区别?

Ami*_*bha 37 java multithreading executorservice

有什么区别

ExecutorService eService = Executors.newFixedThreadPool(2);
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.execute(new TestThread6());
eService.awaitTermination(1, TimeUnit.NANOSECONDS);
eService.shutdown();
Run Code Online (Sandbox Code Playgroud)

eService.shutdown();
eService.awaitTermination(1, TimeUnit.NANOSECONDS);
Run Code Online (Sandbox Code Playgroud)

我真的不明白shutdown().此方法不会等待先前提交的任务完成执行.这是否意味着shutdown()可以终止已提交但未完成的任务?我尝试了一些例子,他们没有证明,请举个例子.

Chr*_*ung 49

你应该先打个电话shutdown.否则,您可能会等待很长时间,因为awaitTermination实际上并没有关闭执行程序.

如果您想等待任务完成,而不是等待执行程序关闭,那么您应该使用invokeAll.

  • 请注意,`shutdown()`不会中断已经执行的任务.来自javadoc:"启动一个有序关闭,其中先前提交的任务被执行,但不会接受任何新任务." 如果你想要中断,你应该调用`shutDownNow()`. (15认同)
  • @ user2245634`awaitTermination`实际上并不首先关闭执行程序.因此,除非另一个线程关闭执行程序,否则`awaitTermination`将一直坐在那里直到超时完成.显然,在你的例子中,你在超时之前只等待1纳秒,这就是为什么你没有观察到"很长时间". (3认同)
  • @AmrishPandey 不,文档不是这么说的。参见SD的回答。你所描述的就是 shutdownNow 所做的。 (2认同)

S.D*_*.D. 40

阅读文档总是有帮助的:

shutdownNow:

尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表.从此方法返回时,这些任务将从任务队列中排空(删除).

此方法不等待主动执行任务终止. 使用awaitTermination来做到这一点.

除尽力尝试停止处理主动执行任务之外,没有任何保证.此实现通过Thread.interrupt()取消任务,因此任何无法响应中断的任务都可能永远不会终止

关机:

启动有序关闭,其中先前提交的任务将被执行,但不会接受任何新任务.如果已经关闭,调用没有其他影响.

此方法不会等待先前提交的任务完成执行.使用awaitTermination这样做.

awaitTermination:

阻止所有任务在关闭请求之后完成执行,或者发生超时,或者当前线程被中断,以先发生者为准.

  • @jrahhali这意味着方法调用立即返回.即调用`shutdown`的线程不会阻塞. (14认同)
  • 我不明白关机的文档.它首先说"先前提交的任务已执行",然后它说"此方法不会等待先前提交的任务完成执行".那么,我的任务是否会完成? (4认同)
  • 啊,不会阻止。现在这很有意义。他们应该使用该词而不是等待。谢谢。 (2认同)

Ter*_* Li 13

shutdown表示执行程序服务不再执行传入任务.

在关闭请求之后调用awaitTermination.

您需要先关闭服务然后阻塞并等待线程完成.

如果要查看所有线程是否已完成运行并坚持使用awaiTermination,则需要将timeout参数设置得足够大.所以你可以这样做:

eService.shutdown();
if (!eService.awaitTermination(60000, TimeUnit.SECONDS))
    System.err.println("Threads didn't finish in 60000 seconds!");
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以这样做:

eService.shutdown();
while (!eService.isTerminated()) {

}
Run Code Online (Sandbox Code Playgroud)

这样,您可以确保所有线程都已完成运行,除非它们意外中断.

  • 不要像第二个代码片段那样忙碌等待.只是.别. (19认同)
  • 你可能意味着毫秒... 60000s是16.666小时. (2认同)
  • @ahrooran 正如@Alexander 指出的,你不应该使用第二个块。这种空体的“while”循环被称为“忙等待”,并将使 CPU 核心保持在 100% 直到完成。考虑到您有可用的“awaitTermination”方法,这是一种浪费。 (2认同)

小智 8

最佳实施:

executor.shutdown();
try {
    if (!executor.awaitTermination(3500, TimeUnit.MILLISECONDS)) {
        executor.shutdownNow();
    }                   
} catch (InterruptedException e) {              
    executor.shutdownNow();
}
        
Run Code Online (Sandbox Code Playgroud)


Ash*_*ari 7

主要区别

关机() -

1. Doesn't block the calling a thread i.e. the thread who called the shutdown().
2. Excecutor doesn't accept any new task after calling shutdown().
Run Code Online (Sandbox Code Playgroud)

awaitTermination() -

1. Blocks the calling thread. (as join() method do)
Run Code Online (Sandbox Code Playgroud)

困惑点:- 如果shutdown() 没有终止之前提交的任务,为什么我们需要awaitTermination()?

awaitTermination 意味着等待任务完成/终止,对吗?shutdown()正在做同样的事情 - 等待已经与正在运行的任务一起提交的任何任务继续直到完成/终止,那么为什么要使用另一种方法awaitTermination(..)?下面是解释:

假设您只能等待10 分钟才能完成所有提交的任务,然后想调用shutdownNow()(---您已经知道它是做什么的)然后awaitTermination(long timeout, TimeUnit unit)在调用 shutdown() 后使用。

注意 中的方法参数awaitTermination(long timeout, TimeUnit unit)。这个超时是这里的关键。

如果没有时间限制,shutdown() 就可以了。不需要 awaitTermination()。