ThreadPoolExecutor源码详解一
ThreadPoolExecutor参数列表
- corePoolSize:核心线程数,除非设置了allowCoreThreadTimeOut,否则核心线程数是保持活动的最小数量0。
- maximumPoolSize:线程池中允许的最大线程数量。
- keepAliveTime:空闲线程等待工作的超时时间(以纳秒为单位)。
- unit:TimeUnit类型,时间单位。
- workQueue:在执行任务之前用于保留任务的队列,此队列将仅保存execute方法提交的Runnable任务。
- threadFactory:执行程序创建新线程时要使用的工厂。
- handler:当达到线程边界和队列容量阻止执行时使用的处理程序。
ThreadPoolExecutor的5种状态
- RUNNING:接收新任务和进程队列任务。
- SHUTDOWN:不接受新任务,但是接收进程队列任务。
- STOP:不接受新任务也不接受进程队列任务,并且打断正在进行中的任务。
- TIDYING:所有任务终止,待处理任务数量为0,线程转换为TIDYING,将会执行terminated钩子函数。
- TERMINATED: terminated()执行完成。
状态之间的转换:
- RUNNING -> SHUTDOWN:调用shutdown()方法
- (RUNNING or SHUTDOWN) ->STOP:调用shutdownNow()方法
- SHUTDOWN -> TIDYING:队列和线程池都是空的
- STOP ->TIDYING:线程池为空
- TIDYING -> TERMINATED:钩子函数terminated()执行完成
4种丢弃策略:
- CallerRunsPolicy:调用execute()方法拒绝任务,由向线程池提交任务的线程来执行该任务
- AbortPolicy: 抛RejectedExecutionException异常(默认的处理方式)
- DiscardPolicy:悄悄地丢弃拒绝的任务
- DiscardOldestPolicy:丢弃最老的未处理的请求,然后重新执行execute()方法
execute方法源码解析
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
addWorker源码解析
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get();
if (runStateOf(c) != rs)
continue retry;
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive())
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}