如果有任何问题请指出,感谢。
ThreadPoolExecutor类实现了ExecutorService接口,他与ScheduledThreadPoolExecutor类的不同是ScheduledThreadPoolExecutor是带有任务调度功能的线程池实现 这个我们之后再讲。
ThreadPoolExecutor使用int的高3位来表示线程池状态,第29位表示线程数量
状态名 | 高3位 | 接收新任务 | 处理阻塞队列任务 | 说明 |
---|---|---|---|---|
RUNNING | 111 | Y | Y | |
SHUTDOWN | 000 | N | Y | 不会接收新任务,但会处理阻塞队列剩余任务 |
STOP | 001 | 会中断正在执行的任务,并抛弃阻塞队列任务 | ||
TIDYING | 010 | 任务全执行完毕,活动线程为0即将进入终结 | ||
TERMINAIED | 011 | 终结状态 | ||
为什么线程池状态与线程池数量要用一个数字表示,而不用两个数字,原因是这两个信息存储在一个原子变量ctl中,这样以后就可以只用一次cas原子操作进行赋值。 |
我们可以看到ThreadPoolExecutor类的构造方法有很多参数,我们一个一个解释
corePoolSize:核心线程数目
maximumPoolSize:最大线程数目
keepAliveTime:生存时间-针对急救线程
unit:时间单位-针对救急线程
workQueue:阻塞队列
threaFactory:线程工厂-可以为线程创建时起名
hander:拒绝策略
我们知道自定义线程池中只有核心线程,所以自定义线程池的流程是:
创建任务->交给空闲的核心线程执行->超出部分的任务放入任务队列->如果此时有空闲核心线程则从任务队列里获取任务执行->如果没有空闲线程 且任务队列也满了->生产线程执行拒绝策略
ThreadPoolExecutor线程池中有核心线程与救急线程,所以ThreadPoolExecutor线程池的流程是:
补充:ThreadPoolExecutor线程池的核心线程没有超时时间,救急线程有。
创建任务->交给空闲核心线程执行->超出部分的任务放入任务队列->如果此时有空闲核心线程->如果此时有空闲核心线程则从任务队列里获取任务执行交给核心的->如果没有空闲线程 且任务队列也满了->创建救急线程 多出的任务交给救急线程执行->如果救急线程也没有空闲了->生产线程执行拒绝策略
可以看出救急线程的作用是在核心线程与任务队列都满的情况下 创建救急线程 如果救急线程在超时时间内没有获取到任务则从线程池中移除。
如果核心线程没有空闲 任务队列满了 救急线程没有空闲,在这种情况下执行拒绝策略,拒绝策略jdk提供了四种实现。