线程池
作用:限制线程数,管理线程、避免频繁创建和销毁线程造成性能损耗
ThreadPoolExecutor
作用
封装线程池的一系列逻辑,通过该类可创建线程池。
构造参数
- corePoolSize 核心线程数,有任务时才会创建线程,一般情况核心线程不会过期,一直占用,除非调
allowCoreThreadTimeOut
方法设置允许过期,核心线程才会因为空闲超时而过期 - keepAliveTime 线程保持存活时间。线程空闲超过指定时间后会超时,默认是超过
核心线程数
创建的线程才会超时终止。如果调用了allowCoreThreadTimeOut方法设置为true,则核心线程池超过空闲时间也会被回收。 - unit 指定超时时间的时间单位,TimeUnit有7个时间单位选择
- workqueue 工作队列,当线程数超过核心线程数时,请求会进入队列中等待分配线程。不同的队列进队出队有些区别。
- maximumPoolSize 最大线程数,表示线程池最大允许创建的线程数,当阻塞队列满了之后才会尝试继续创建线程,如果超过最大线程数,则会触发拒绝策略。
- RejectedExecutionHandler 拒绝处理器,当阻塞队列满了、并且当前线程数大于最大线程数时,请求获取线程会被拒绝,不同的拒绝策略有不同的执行方式。
execute方法分析
works变量: 工作线程集合,存储处于运行状态的线程。
执行流程如下
- 首先获取当前处于工作状态的线程数,如果小于
核心线程数corePoolSize
,则将当前执行runnale封装成worker
类,通过worker类(本身也是实现runnale)创建线程,加入处于工作状态的集合,并调用线程的start
执行。 start方法会执行worker类的run方法,该方法会先执行当前任务
,当前任务执行结束后,去阻塞队列workqueue
中取出其他任务,取到任务则继续执行。如果核心线程允许超时或者线程大于核心线程数,则会用阻塞队列的poll方法指定keepAliveTime
等待时间,在这个时间内如果没有新的任务进入队列,则不再等待,停止执行。- 如果处于工作状态的线程数小于核心线程数,则
cas修改工作线程数
加入工作线程集合(cas失败是因为并发都去加入队列,要重新再判断再cas)。如果工作状态的线程数大于核心线程数,则加入阻塞队列workqueue
。 - 如果加入队列失败,则会判断是否处于工作状态的线程是否大于
最大线程数maximumPoolSize
,如果没有则尝试加入工作线程集合,封装worker创建线程,调用start方法执行。 - 如果大于
最大线程数maximumPoolSize
则调用拒绝执行处理器进行拒绝处理。