一、概念
可以简单理解为统一管理线程生命周期的池子
作用
- 提高响应速度;避免人为的创建和销毁线程带来的不便,交由线程池统一管理
- 重复利用线程,节省资源
二、任务处理流程
三、核心属性
属性 | 说明 | 备注 |
corePoolSize | 线程池中的核心线程数 | |
maximumPoolSize | 线程池中的最大线程数 | |
| 阻塞队列 | 存储工作任务 |
| 等待工作的空闲线程的超时(以纳秒为单位) |
核心线程也启用该时间,超时则关闭; |
| 是否允许核心线程超时 | true:核心线程达到keepAliveTime后关闭 false:核心线程一直等待任务 |
| 拒绝执行策略处理器 | 在线程池饱和或关闭时,启用该策略,常用有以下几种 1、AbortPolicy (默认,抛异常) 2、CallerRunsPolicy 3、DiscardOldestPolicy 4、DiscardPolicy
|
| 包含所有工作线程的集合。 只有当持有mainLock才可访问 |
每一个Worker本身都实现了Runnable接口 |
| 曾经出现过的最大线程数 | 一般用于跟踪记录线程池是否已满等监控操作 |
| 完成的任务数 | |
| 线程工厂,用于创建新线程 |
四、线程池中的状态
注:线程池各种状态对当前池中的任务和新任务处理逻辑是不同的、
-
RUNNING 初始状态
-
SHUTDOWN 调用shutdown()之后
-
STOP 调用shutdownNow()之后
-
TIDYING 从Shutdown或Stop转成TIDYING
-
TERMINATED 然后从TIDYING立刻转成TERMINATED
五、线程池实现的基本原理
- 线程池 通过AtomicInteger的32位int值表示状态和线程个数,
- 通过BlockingQueue实现阻塞队列,
- 通过workers集合存放工作任务,因为Worker本身就是实现Runnable接口,直接调用run方法就可以启动任务线程。
- 通过runWorker(Worker w)方法,不断的去阻塞队列获取任务并执行来达到线程复用的目的(参考getTask()方法)。
六、问题
- AtomicInteger下的int value是如何表示线程状态和线程个数的?
- 线程池中的核心参数的作用是什么?
- 不同的线程状态,针对池中的任务和新任务是怎么处理的?
- 线程是如何做到复用的?
- 拒绝策略何时执行?如何区分使用不同的拒绝策略?
- 为什么阿里手册不建议使用Executors创建线程?各个创建方式使用场景和弊端是什么?
- 当达到核心线程数时,为什么采用直接丢队列中,而不是直接创建非核心线程来执行任务?
- 当线程发生中断时会发生什么情况?
- 总结一下线程池的设计思想及源码?