在使用线程池的时候,我们会使用到提交线程池的方法execute()。
public void execute(Runnable command) {
e.execute(command);
}
它的主要作用是提交执行任务,参数支持Runnable, execute()没有返回值,同时,它的任务里必须捕获异常。
execute()的工作主要流程如下图所示:
接下来就主要去看看这个execute()方法的源码含义
1.当传入一个 null的 Runnable的时候,会进行抛出异常
if (command == null)
throw new NullPointerException();
2.获取最新的ctl值
int c = ctl.get();
3.进行了一次 workerCountOf© 和当前线程池核心数的比较,如果true,则可以提交此次线程数量,进行创建一个worker
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
4.再往下走,表示addworker失败了,或者当前线程数量 > corePoolSize,进入到方法后,再次获取最新的数量
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);
}
5.最后都不满足条件的话,走到了最后一个条件,表明当前线程池是非Running状态
else if (!addWorker(command, false))
reject(command);
该方法的具体描述如下:
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.
*/
// c : 获取ctl最新值
int c = ctl.get();
// workerCountOf(c) 获取当前线程的数量 true: 表示当前线程数量 < 核心线程数量
// 表示此次提交线程数量,直接创建一个新的 worker.
if (workerCountOf(c) < corePoolSize) {
// core == true 表示采用核心线程数量限制 false 表示采用 maximumPoolSize
if (addWorker(command, true))
// 创建成功后, 直接返回
return;
// 创建失败:
// 1.存在并发现象
// 2.当前线程池状态发生了改变 Running SHUTDOWN STOP TIDYING , 当线程池状态非Running 会失败
// 3.
c = ctl.get();
}
// 执行到这里的情况:
// 1.当前线程数达到了 corePoolSize
// 2. addWorker失败了
if (isRunning(c) && workQueue.offer(command)) {
// 再次获取ctl的最新值
int recheck = ctl.get();
// 条件一: ! isRunning(recheck) 成立: 说明你提交到队列之后,线程池状态被外部修改了
// 条件二: remove(command); true: 提交之后,线程池中的线程还未被消费
if (! isRunning(recheck) && remove(command))
// 提交之后,线程池状态为非Running , 且任务出队成功,
reject(command);
// workerCountOf(recheck)为 true:
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
// 执行到这里的情况
// 1. offer() 失败
// 2.当前线程池是非Running状态
// 1.
else if (!addWorker(command, false))
reject(command);
}