ExecutorService 中 shutdown()shutdownNow()awaitTermination() 含义和区别

Posted 猎人在吃肉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ExecutorService 中 shutdown()shutdownNow()awaitTermination() 含义和区别相关的知识,希望对你有一定的参考价值。

文章目录


ExecutorService 是 Java 提供的线程池,也就是说,每次我们需要使用线程的时候,可以通过 ExecutorService 创建线程。

使用 ExecutorService 类时,经常用到 shutdown()shutdownNow()awaitTermination() 3个方法,下面我们来说说它们的含义和三者的区别 。

一、方法说明

1、shutdown():停止接收新任务,原来的任务继续执行

英文原意:关闭,倒闭;停工。 这里的意思是 关闭线程池与使用数据库连接池一样,每次使用完毕后,都要关闭线程池。

1、停止接收新的submit的任务;
2、已经提交的任务(包括正在跑的和队列中等待的),会继续执行完成;
3、等到第2步完成后,才真正停止;

2、shutdownNow():停止接收新任务,原来的任务停止执行

1、跟 shutdown() 一样,先停止接收新submit的任务;

2、忽略队列里等待的任务;

3、尝试将正在执行的任务interrupt中断;

4、返回未执行的任务列表;

说明:它试图终止线程的方法是通过调用 Thread.interrupt() 方法来实现的,这种方法的作用有限,如果线程中没有sleep 、wait、Condition、定时锁等应用, interrupt() 方法是无法中断当前的线程的。所以,shutdownNow() 并不代表线程池就一定立即就能退出,它也可能必须要等待所有正在执行的任务都执行完成了才能退出。但是大多数时候是能立即退出的。

3、awaitTermination(long timeOut, TimeUnit unit):当前线程阻塞

timeout 和 TimeUnit 两个参数,用于设定超时的时间及单位

当前线程阻塞,直到:

  • 等所有已提交的任务(包括正在跑的和队列中等待的)执行完;
  • 或者 等超时时间到了(timeout 和 TimeUnit设定的时间);
  • 或者 线程被中断,抛出InterruptedException

然后会监测 ExecutorService 是否已经关闭,返回true(shutdown请求后所有任务执行完毕)或false(已超时)

二、区别

1、shutdown() 和 shutdownNow() 的区别

shutdown() 只是关闭了提交通道,用submit()是无效的;而内部该怎么跑还是怎么跑,跑完再停。
shutdownNow() 能立即停止线程池,正在跑的和正在等待的任务都停下了。

2、shutdown() 和 awaitTermination() 的区别

shutdown() 后,不能再提交新的任务进去;但是 awaitTermination() 后,可以继续提交。

awaitTermination()是阻塞的,返回结果是线程池是否已停止(true/false);shutdown() 不阻塞。

三、总结

1、优雅的关闭,用 shutdown()

2、想立马关闭,并得到未执行任务列表,用shutdownNow()

3、优雅的关闭,并允许关闭声明后新任务能提交,用 awaitTermination()

4、关闭功能 【从强到弱】 依次是:shuntdownNow() > shutdown() > awaitTermination()

以上是关于ExecutorService 中 shutdown()shutdownNow()awaitTermination() 含义和区别的主要内容,如果未能解决你的问题,请参考以下文章

在webapp中优雅地关闭ExecutorService?

ExecutorService.invokeAny()和ExecutorService.invokeAll()的使用剖析

Java线程池 ExecutorService了解一下

ExecutorService 的未来任务没有真正取消

Executor与ExecutorService

ExecutorService.submit()与Executor.execute()的区别