public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) { // 如果线程数小于corePoolSize则创建新线程
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) { // 如果线程数大于等于corePoolSize则尝试把线程放进阻塞队列中
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); // 线程数大于maxPoolSize时调用拒绝策略
}
提交任务的过程可以总结为:如果线程数没达到corePoolSize则创建线程,如果达到了且阻塞队列未满则放入阻塞队列,如果队列满了且在线程数没达到maxPoolSize会创建先线程,如果以上条件都不满足则调用拒绝策略。
提交时用到的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))
// 线程数超过corePoolSize或maxPoolSize则不会开启新线程
return false;
if (compareAndIncrementWorkerCount(c)) // CAS将任务数+1成功以后跳出循环
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 {
// 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) // 加入失败将workCount-1
addWorkerFailed(w);
}
return workerStarted;
}