Java线程池的关闭, shutdown和shutdownNow的区别

本文详细解析了Java线程池中shutdown与shutdownNow方法的区别。shutdown仅标记关闭,执行积压任务而不打断正在执行的任务;shutdownNow则尝试打断正在执行的任务,并返回被打断的任务列表。文章还介绍了如何正确判断线程池的关闭状态及如何等待线程池完全关闭。
摘要由CSDN通过智能技术生成

Java线程池shutdown和shutdownNow的区别

结论

先说结论

  1. shutdown 标记关闭 + 会执行积压任务(因线程不足而放入queue里的) + 不打断正在执行的任务 + 之后不允许添加新任务
  2. shutdownNow = 标记关闭 + 不执行积压任务 + 打断(通过线程interrupt)正在执行的任务 + 之后不允许添加新任务
  3. 对于停不下来的任务只能等到任务结束, 此过程 isTerminating 返回 true, 可以使用 awaitTemination 阻塞地等到真正关闭
  4. 等所有任务都停止运行了才算是真正关闭, 此时 isTerminated 返回 true
  5. 对于 ScheduledThreadPoolExecutor, setExecuteExistingDelayedTasksAfterShutdownPolicy(默认是true)可以控制shutdown之后是否执行积压的一次性任务(通过execute/schedule生成的一次性任务)

介绍

在java中, 普通线程池通常使用 ExecutorService 接口, 具备调度能力的通常使用 ScheduledExecutorService(扩展了ExecutorService). 

ExecutorService上有几个跟关闭线程池相关的方法.

  1. shutdown: 停止线程池, 但不打断(通过线程interrupt)正在执行的任务
  2. shutdownNow: 停止线程池, 会打断(通过线程interrupt)正在执行的任务并返回被打断的List<Runnable>
  3. isShutdown: 用于判断shutdown是否已经被调用过, 及时返回true也不代表线程池已经真正关闭了
  4. isTerminated: 用于判断线程池是否已经真正关闭
  5. awaitTermination: 等待线程池真正关闭

具体的实现类 ThreadPoolExecutor 上还有

  1. isTerminating: 是否正在关闭中

显然, 线程池的关闭是一个过程, 需要一些时间, 因为有一些任务正在执行, 并且无法被打断,调用shutdown了之后可能有任务还在继续执行, 不过可以保证的是肯定不会有新的任务加进来执行了.

因此需要结合shutdown/awaitTermination的组合才能确线程池真正关闭.

 

另外, 具体的实现类 ScheduledThreadPoolExecutor 上还有

  1. setContinueExistingPeriodicTasksAfterShutdownPolicy: 默认是false, 建议设置成false就好, 该属性用于控制shutdown了之后是否继续执行已存在的periodic tasks(周期性执行的任务, 通过 scheduleWithFixedRate/withFixedDelay 提交的任务), 这通常不是想要的, 除非需要很精细话控制整个shutdown流程, 需要用户手动cancel掉这些任务才能真正达到terminated.
  2. setExecuteExistingDelayedTasksAfterShutdownPolicy: 默认是true, 该属性用于控制shutdown了之后是否继续执行已存在的一次性任务(通过 execute/schedule 方法提交的任务).
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值