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);
}
execute方法中的步骤:
- 如果当前正在运行的线程数小于corePoolSize的话,那么尝试使用传入的command作为第一个任务启动一个新的线程执行。addWorker函数会原子性的检查runState以及workerCount防止不应该添加的新线程被添加。如果是假警报的话,那么addWorker函数就会返回false,表示添加新线程失败。
- 如果一个Task被成功的加入队列了,然后仍然需要重新check一次是否需要重新添加一个线程,因为有可能在上一次检查到这次检查之间,已经存在的线程已经死亡。或者,自从进入这个方法后,线程池已经被shut down。所以我们需要重新check状态,并且在必要的时候,如果处于stopped状态,需要重新回滚到队列中,或者如果没有的话,就需要重新启动一个线程。
- 如果不能把task加入到队列中,那么就会尝试去添加一个新的线程,如果它失败了,就知道是已经当前线程池是处于shut down或者处于饱和状态,那么就执行reject操作。
函数执行流程:
- 通过workCountOf(c)拿到ctl中存储的当前线程总数,如果小于corePoolSize,那么就会走到addWorker方法中,如果成功创建了Worker的话,那么返回true,直接return,否则重新通过cas拿一次c
- 判断当前的线程池是否处于RUNNING状态,如果是,并且workQueue.offer加入队列成功话,那么那么就重新拿出来一次ctl,再判断如果加入队列之后,线程池如果不是处于RUNNING的状态,并且从队列中remove成功的话,那么就会执行reject操作
- 判断当前线程数是否为0,如果为0的话,那么就调用addWorker(null,false),否则如果非Running状态或者加入队列失败的话,那么就会调用addWorker(command,false)如果返回false,说明没有添加成功,就会执行reject操作。
网友评论