上一篇简单介绍了一下ThreadPoolExecutor的一些比较重要的常量,接下来主要来跟踪一下最主要的execute方法。
上源码:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
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);
}
代码非常的简洁,一个参数,Runnable类型的变量,前文中我们已经介绍过线程运行的原理,线程最终在执行时,会执行Runnable对象的run方法。接下来,我们将逐步分析代码:
int c = ctl.get();
获取ctl的值,由于ctl是一个原子整型,通过get方法可以获取到当前的值,前3位标识状态,后29位标识线程数量。
if (workerCountOf(c) < corePoolSize) {
workerCountOf方法,我们在前文已经介绍过,可以计算出ctl的后29位线程数。corePoolSize为ThreadPoolExecutor构造函数里面的初始值,标识核心线程的运行数量。判定当前线程数小于核心线程数时,进入函数体。
if (addWorker(command, true))
调用addWorker方法,command为我们传递的Runnable对象,接下来我们来跟踪一下addWorker方法,源码:
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
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(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
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 {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
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;
}
假设我们第一次调用execute方法,那么ctl的当前值为1110 0000 0000 0000 0000 0000 0000,前3位为Running状态,后29位运行线程数为0。查看addWorker第一段代码,2个无限的循环体:
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
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(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
获取ctl的值,再通过ctl获取线程池状态(runState - rs,下文简称rs),当前rs值应为RUNNING,所以第一个判定:
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
在正常运行的情况下,没有外部调用shutdown方法或者出现异常时,不会通过判定,会直接运行下一段代码,同样为一个无限循环体:
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
workCount - wc(下文简称wc),当前活动线程数,在无特殊情况下,第一个判定不会为true,因为CAPACITY的容量很大,第二个判定,core为ture时,判断活动线程数是否大于核心线程数,false时判定是否大于最大池边界值数量,如果判定通过,直接结束方法体,返回false,此时的wc数应为0,不通过判定,直接运行下一步。
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
compareAndDecrementWorkerCount是对ctl的一个原子操作:
private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
比对expect的值是否等于实际值,如果等于,将当前值加一,返回true。注意:由于ThreadPoolExecutor对象是在一个多线程的环境中,所以可能出现其他的线程在此期间修改过ctl的值,那么此时的设定就会失败,返回一个false值。
如果设定成功,会直接跳出最外层的循环,如果失败,重新获取ctl的值,再重新判定rs是否发生变更,如果rs发生变更,执行外层下一次循环,如果未变更,执行当前下一次循环。
假设我们设定成功,此时ctl的值将会变为:1110 0000 0000 0000 0000 0000 0000 0001,查看下一段代码:
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
设定一些局部变量,然后开始一个try-catch方法体:
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
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);
}
通过上诉代码,我们可以看见一个Worker对象被创建,随后worker的一个全局变量thread被赋值给一个临时变量,而最终会调用这个临时变量的start方法,那么此时的线程就会真正的启动了,随后run方法也会被调用。
private final HashSet<Worker> workers = new HashSet<Worker>();
// ... some code
workers.add(w);
workers是一个全局变量,用来保存worker对象在内存中的一个持久化存储,在worker保存成功后,workerAdded的值会设置为true,随后调用t.start方法,启动线程。
下文中,我们将解析一下Worker的代码,来分析线程池是如何实现池的功能的!