为什么我们需要使用`awaitTermination`而不仅仅是`shutdownNow()`呢?

huangapple go评论78阅读模式
英文:

Why do we need to use awaitTermination but not just shutdownNow()?

问题

我正在按照Oracle推荐的标准流程来关闭执行者服务。以下是推荐的代码部分:

void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // 禁止提交新任务
   try {
     // 等待一段时间,让现有任务终止
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // 取消当前正在执行的任务
       // 等待一段时间,让任务响应取消操作
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // 如果当前线程也被中断,则(重新)取消
     pool.shutdownNow();
     // 保留中断状态
     Thread.currentThread().interrupt();
   }
}

我阅读了关于shutdown()awaitTerminationshutdownNow()的描述;

我理解:

  • shutdown() 只停止提交新线程。
  • awaitTermination 等待运行中的线程被关闭。在完成执行、超时或当前线程中断的情况下返回一个值。
  • shutdownNow() 使用 Thread.interrupt() 来中断线程。

我的问题是,如果我确定我的线程只使用可以被 Thread.interrupt() 中断的 sleep,那么是否仍然有必要像Oracle推荐的那样调用 awaitTermination

我知道 shutdownNow() 有可能无法关闭线程,但为什么我们不能继续像这样做,强制停止线程,然后查看是否仍有未停止的线程呢?

pool.shutdown();
pool.shutdownNow();
try {
   if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       System.err.println("Pool did not terminate");
   }
} 
英文:

I am following the standard process that was recommended by oracle to shut down the executor services. here is the code that was recommended:

 void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // Disable new tasks from being submitted
   try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 }

I read through the descriptions for shutdown(), awaitTermination, and shutdownNow();

I understand that
shutdown() only stop submitting new threads.

awaitTermination waits for the running threads to be shutdown. Returns a value if one of completed execution, time out or current thread interrupted.

shutdownNow() use Thread.interrupt() to interrupt threads.

My question is, if I know for sure that my threads only use sleep which can be interrupted by Thread.interrupt(). Is there still a value to call awaitTermination like what oracle recommended?

I know that shutdownNow() might have a chance to not shutdown a thread, but why can't we go ahead and do something like this to force stop the threads then see if there are still threads not stoped?

pool.shutdown();
pool.shutdownNow();
  try {
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
           System.err.println("Pool did not terminate");
     }
   } 

答案1

得分: 2

“标准流程”只是试图优雅地处理关闭,前提是在不必要时不中断线程。

首先,它停止接受新的任务提交,让正在进行的任务完成它们的工作。只有当它们在优雅期限内未完成时,才会继续进行强制终止。

英文:

The "standard process" just tries to handle the shutdown gracefully, the premise being not to interrupt the threads when it's not necessary.

First it stops accepting new task submissions and lets the ongoing tasks finish their work. It proceeds to forceful termination only when they don't finish within the grace period.

huangapple
  • 本文由 发表于 2020年8月27日 06:59:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/63606845.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定