概述
ThreadPoolExecutor 是 JDK 中线程池的实现类,开发过程中,合理地使用线程池可以有很多好处:
降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行。
提高线程的可管理性:线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。
它的继承结构如下:
源码分析
构造方法:
ThreadPoolExecutor 内部有多个构造器
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
最终都是调用参数最多这个:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null : AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
成员变量:
// 任务队列(阻塞队列)
private final BlockingQueue<Runnable> workQueue;
// 互斥锁
private final ReentrantLock mainLock = new ReentrantLock();
// 工作线程集合
private final HashSet<Worker> workers = new HashSet<Worker>();
// 锁对应的条件
private final Condition termination = mainLock.newCondition();
// 线程池创建过的最大线程数量
private int largestPoolSize;
// 已完成任务的数量
private long completedTaskCount;
// 线程工厂类,用于创建线程
private volatile ThreadFactory threadFactory;
// 拒绝策略
private volatile RejectedExecutionHandler handler;
// 空闲线程的存活时间
private volatile long keepAliveTime;
/*
* 核心线程是否允许超时
* 默认为 false,表示核心线程即使处于空闲状态也继续存活;
* 若为 true,核心线程同样受到 keepAliveTime 的超时约束
*/
private volatile boolean allowCoreThreadTimeOut;
// 核心池大小
private volatile int corePoolSize;
// 最大池大小
private volatile int maximumPoolSize;
// 默认拒绝策略
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
参数解析:
corePoolSize: 核心池大小;
maximumPoolSize: 最大池大小,线程池中能同时存在的最大线程数,大于等于 corePoolSize;
workQueue: 工作/任务队列,是一个阻塞队列,可参考前文「JDK源码分析-BlockingQueue」的分析。
若 allowCoreThreadTimeOut 为 false (默认),且线程数量超出 corePoolSize,则空闲时间超过 keepAliveTime 的线程会被关闭(最多保留 corePoolSize 个线程存活);
若将 allowCoreThreadTimeOut 设为 true,核心池的线程也会受该超时的影响而关闭。
向线程池提交任务的流程:
1、初始化一个容量为 corePoolSize 的池子;
2、刚开始,每来一个任务就在池中创建一个线程去执行该任务,直到池中的容量到达 corePoolSize;
3、此时若再来任务,则把这些任务放到 workQueue 中;
4、若 workQueue 也满了,则继续创建线程执行任务,直到线程数量达到 maximumPoolSize;
5、若 workQueue 已满,且线程数量达到 maximumPoolSize,此时若还有任务到来,则执行拒绝策略(handler)。
线程池相关其他方法后续学习补充~