源码分析之Java线程池ThreadPoolExecutor
我个人觉得,学习源码的姿势,首先是需要知道想学习的框架/工具如何使用,然后接下来再去看源码注释,看看当时代码作者是如何阐述代码的,再去看代码怎么编写,效果才最佳。
同样的,接下来要分析的线程池,首先用途自不必说,不管有没有用过,ThreadPoolExecutor的运行机制、传说中的7个参数(核心线程数corePoolSize、最大线程数maxPoolSize、等待时间keepAliveTime、时间单位timeUnit、阻塞队列blockingQueue、线程工厂threadFactory、拒绝策略rejectHandler),相信大家都已经熟练掌握,此处不再赘述。
接下来简单过一下ThreadPoolExecutor的注释。\
0. 源码注释中的关键点
ThreadPoolExecutor的类注释中,主要阐述如下内容:
- 有关运行机制、7个参数如何使用与配合
- 还有一些细节,比如阻塞队列,可以有3种选择:
- direct handoff
- unbounded queue
- bounded queue
- 其他可能有用的信息:
- 线程池的hook方法:beforeExecute(Thread, Runnable), afterExecute(Runnable, Throwable)。若hook抛出异常,则当前线程也会异常终止。
- getQueue() 可以获取工作队列,可以用来monitor和debug,不推荐用于其他用途。提供了两个接口: remove(Runnable) , purge()
- 线程池对象在程序中不被引用,并且没有线程时,该线程池将会被自动关闭。
- 线程池状态的说明
ThreadPoolExecutor有一个AtomicInteger变量ctl表示,该变量包含了两个含义:
高3位表示当前线程池状态
- “`\ \
- RUNNING: Accept new tasks and process queued tasks \
- SHUTDOWN: Don't accept new tasks, but process queued tasks \
- STOP: Don't accept new tasks, don't process queued tasks, \
- and interrupt in-progress tasks \
- TIDYING: All tasks have terminated, workerCount is zero, \
- the thread transitioning to state TIDYING \
- will run the terminated() hook method \
- TERMINATED: terminated() has completed \
- 状态转移。这些状态支持比较,因为JDK实现时,The runState monotonically increases over time, but need not hit each state.- \
- RUNNING -> SHUTDOWN \
- On invocation of shutdown(), perhaps implicitly in finalize() \
- (RUNNING or SHUTDOWN) -> STOP \
- On invocation of shutdownNow() \
- SHUTDOWN -> TIDYING \
- When both queue and pool are empty \
- STOP -> TIDYING \
- When pool is empty \
- TIDYING -> TERMINATED \
- When the terminated() hook method has completed “`
剩余的低29位表示线程池的数量(所以目前的版本只有支持2^29-1个线程)
下面将结合代码,解说线程池的关键流程。
1. 常用变量的解释
1 | // 1. `ctl`,可以看做一个int类型的数字,高3位表示线程池状态,低29位表示worker数量 |
2. 构造方法
1 | public ThreadPoolExecutor(int corePoolSize, |
3. 提交执行task的过程
1 | public void execute(Runnable command) { |
4. addworker源码解析
1 | private boolean addWorker(Runnable firstTask, boolean core) { |
5. 线程池worker任务单元
1 | private final class Worker |
6. 核心线程执行逻辑-runworker
1 | final void runWorker(Worker w) { |