Java ThreadPoolExecutor 学习笔记(三)

ThreadPoolExecutor 的关闭流程很简单

[b]void shutdown()[/b]
1. 获取 mainLock 锁
2. 当前的状态如果是 SHUTDOWN ,STOP ,TIDYING ,TERMINATED 则退出
3. 如果不是则 CAS 设置状态为 SHUTDOWN
4. CAS 失败则回到 step 2 继续
5. 对所有 Worker 线程调用 interrupt() 中断阻塞
6. 释放 mainLock ,调用 tryTerminate() 关闭线程池

[b]step 5 中断所有线程后,新的任务不能再提交进来,但是 worker 线程并不会立即退出,会继续从 workQueue 取出并执行任务,直到没有任务后再退出。所以调用 shutdown() 的线程在这里不会被阻塞,线程池会等待 workQueue 里面所有任务执行完毕以后才会变成 TERMINATED。[/b]


[b]void tryTerminate()[/b]
1. 获取当前的线程数量,线程池状态
2. 如果线程池状态是 RUNNING、 TIDYING、 TERMINATED 直接返回
3. 如果线程池是 SHUTDOWN,但是 workQueue 还有 task,直接返回
4. 到这步,线程池状态应该是 SHUTDOWN 并且 workQueue 已经没有 task,或者是 STOP。如果线程池里面还有线程存活,call interruptIdleWorkers(true) 从 workers 里面去关闭一个闲置线程 (为什么只关闭一个?),return
5. 到这步,线程池状态应该是 SHUTDOWN 或者 STOP,workQueue 已经没有 task,线程池里面没有线程存活。获取 mainLock, CAS 操作设置状态为 TIDYING 。如果 CAS 成功,则再次设置状态为 TERMINATED, call termination.signalAll()唤醒等待线程池关闭的线程(外部线程可能 call awaitTermination(long timeout, TimeUnit unit)等待线程池彻底关闭)
6. 释放mainLock

[b]这里的疑惑为 step 4,当线程池里面还有线程存活的时候,尝试去关闭最多一个线程。为什么是只关闭最多一个?而不是全部?注意 step 5,CAS操作设置状态为 TIDYING 。这是因为前面检查状态都是在没获取 mainLock 情况下完成的,在获取 mainlock 后重复检查成功,之后才设置 TERMINATED 状态并唤醒等待线程池关闭的线程[/b]


[b]List<Runnable> shutdownNow()[/b]
1. 获取 mainLock 锁
2. 当前的状态如果是 STOP ,TIDYING ,TERMINATED 则退出
3. 如果不是则 CAS 设置状态为 STOP
4. CAS 失败则回到 step 2 继续
5. 对所有 Worker 线程调用 interrupt() 中断阻塞
6. 从 workQueue 里面取出所有任务,
7. 释放 mainLock ,调用 tryTerminate() 关闭线程池。返回 workQueue 里没有被执行的任务。


[b]shutdownNow() 和 shutdown() 流程很类似,但是调用后不会等待 Worker 线程继续执行已经提交任务。相反,当前调用线程会取出任务返回。 [/b]

[b]boolean awaitTermination(long timeout, TimeUnit unit)[/b]
1. 获取 mainLock 锁
2. 当前的状态如果是 TERMINATED 则返回 true
3. 如果不是,使用和 mainLock 关联的条件 termination.awaitNanos(nanos) 等待 指定时间,超时后状态还不是 TERMINATED。 返回false。
4. 释放 mainLock 锁


[b]调用 awaitTermination 的线程会被阻塞最多指定时间,最后是否关闭线程池成功需要判断返回值。[/b]

[url=http://vampiredx.iteye.com/blog/2206223]Java ThreadPoolExecutor 学习笔记(一)[/url]
[url=http://vampiredx.iteye.com/blog/2211153]Java ThreadPoolExecutor 学习笔记(二)[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值