/**
* Executes the given task sometime in the future. The task
* may execute in a new thread or in an existing pooled thread.
* 在未来某个时间执行指定传入的任务。
* 任务可以在一个新线程中执行,也可能在线程池中已存在的一个线程中执行。
* If the task cannot be submitted for execution, either because this
* executor has been shutdown or because its capacity has been reached,
* the task is handled by the current {@code RejectedExecutionHandler}.
* 如果这个任务不能被提交执行,或者是因为这个executor已经被shutdown,又或者因为已经触及线程池的最大容量,
* 这个任务被当前的拒绝策略RejectedExecutionHandler处理掉了
* @param command the task to execute
* @throws RejectedExecutionException at discretion of
* {@code RejectedExecutionHandler}, if the task
* cannot be accepted for execution
* @throws NullPointerException if {@code command} is null
*/
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.
* 如果线程池当前正在运行的线程数小于corePoolSize,将尝试新起一个线程,传入的Runnable command将作为它的第一个任务。
* 调用addWorker将原子性的检查runState线程池运行状态和workerCount工作者数量,并且当不应该新增线程时通过return 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.
* 如果一个任务能够成功的加入队列,这时我们仍然需要再次检查我们是否应该新起一个线程(因为从上次检查之后已存在的线程有可能消亡了)
* 或者进入此方法后线程池shutdown了。
* 所以我们还是要重新检查线程池状态,以及当线程池停止是否有必要将入队列的操作回滚,
* 或者线程池中没有线程时需要新起一个线程
* 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.
* 如果不能将任务入队列,这时我们尝试新起一个线程,如果新起线程失败,我们就知道线程池已经被shutdown或者线程池饱和了,
* 这时就需要拒绝任务了
*/
int c = ctl.get();
//如果worker的数量小于corePoolSize
if (workerCountOf(c) < corePoolSize) {
//如果添加任务成功就可以返回了
if (addWorker(command, true))
return;
c = ctl.get();
}
//如果workerCount不小于核心线程数,那么接下来尝试放到blockingqueue了
//ctl<SHUTDOWN且入队列成功
if (isRunning(c) && workQueue.offer(command)) {
//二次检查ctl
int recheck = ctl.get();
//ctl>=SHUTDOWN且移除任务成功
if (! isRunning(recheck) && remove(command))
//拒绝任务
reject(command);
//如果workerCount==0,这时候创建空的worker,使用maximumPoolSize
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//接下来是尝试添加超过corePoolSize,<=maximumPoolSize,如果添加失败则采用拒绝策略
else if (!addWorker(command, false))
reject(command);
}
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
//得到ctl
int c = ctl.get();
//c & ~CAPACITY 只保留高3位状态位1
int rs = runStateOf(c);
// Check if queue empty only if necessary.
//3种情况,1、线程池>SHUTDOWN
// 2、线程池状态==SHUTDOWN 且firstTask != null
// 3、线程池状态==SHUTDOWN 且firstTask == null且workQueue.isEmpty()
//当firstTask为空时是为了创建一个没有任务的线程,再从workQueue中获取任务,如果workQueue已经为空,那么就没有添加新worker的必要了
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
//workCount
int wc = workerCountOf(c);
//如果workCount>=最大线程数容量或者>=core
//core是传进来的参数,true代表使用corePoolSize计量,false代表使用maximumPoolSize
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
//如果cas操作将WorkerCount+1成功,直接break外层循环,继续往下走
if (compareAndIncrementWorkerCount(c))
break retry;
//重新get ctl
c = ctl.get(); // Re-read ctl
//如果runstate变了就要重新从外层循环开始判断
if (runStateOf(c) != rs)
continue retry;
//否则走到这里只能是因为workerCount变了导致cas失败,这时重新开始内层循环
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
//new一个worker
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());
//若线程池状态<SHUTDOWN或
// ==SHUTDOWN且是一个空任务
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
//如果线程已经启动,抛异常
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
//把new worker添加到worker set中
workers.add(w);
int s = workers.size();
//largestPoolSize用来记录线程池线程数曾达到的最大值
if (s > largestPoolSize)
largestPoolSize = s;
//标记worker已添加
workerAdded = true;
}
} finally {
mainLock.unlock();
}
//标记worker已添加到worker set中,启动线程标记为已启动
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
//如果worker未启动,进行添加worker失败的后续处理
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
/**
* Rolls back the worker thread creation.
* 回滚创建worker线程的操作
* - removes worker from workers, if present
* 从worker set移除此worker
* - decrements worker count
* worker count递减
* - rechecks for termination, in case the existence of this
* worker was holding up termination
* 重新检查是否要terminate,防止是由于这个回退worker hold住了线程池使其不能停止
*/
private void addWorkerFailed(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (w != null)
workers.remove(w);
//循环尝试,直到cas成功,完成计数-1
decrementWorkerCount();
//尝试停止线程池
tryTerminate();
} finally {
mainLock.unlock();
}
}
/**
* Transitions to TERMINATED state if either (SHUTDOWN and pool
* and queue empty) or (STOP and pool empty). If otherwise
* 如果线程池处于SHUTDOWN状态且线程池及队列都为空,或者STOP且线程池为空,转换成TERMINATED状态
* eligible to terminate but workerCount is nonzero, interrupts an
* idle worker to ensure that shutdown signals propagate. This
* 如果符合terminate的条件但workerCount不为0,则中断一个空闲worker以保证这个shutdown信号被传递
* method must be called following any action that might make
* termination possible -- reducing worker count or removing tasks
* 此方法应该在任何可能导致线程池终止的操作之后被调用,这些操作可能是worker数量被减少或者在shutdown的时候从线程队列移除了任务
* from the queue during shutdown. The method is non-private to
* allow access from ScheduledThreadPoolExecutor.
* 此方法不是私有的,为了能够让ScheduledThreadPoolExecutor访问到
*/
final void tryTerminate() {
for (;;) {
int c = ctl.get();
//c < SHUTDOWN还处于运行状态
//或者已经是TIDYING或者TERMINATED状态了,就无需再tryTerminate
//或者状态是SHUTDOWN但工作队列不为空,这时候也不能tryTerminate
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
//如果能再往下走,说明处于SHUTDOWN状态且workQueue是空的
//如果worker数量不为0,这时候去中断一个空闲的worker,即用中断去唤醒一个阻塞在从workqueue获取任务的core线程,且只中断一个
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//cas将线程池状态变为TIDYING,workercount变为0
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
//如果cas成功了就调用terminated,这里应该可以看成是一个钩子方法,本身是个空方法,由子类去override
terminated();
} finally {
//最后把ctl设置成TERMINATED,workercount为0
ctl.set(ctlOf(TERMINATED, 0));
//唤醒那些调用了awaitTermination()等待线程池终止的线程
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}