前言:很多时候我们需要使用线程池来处理逻辑,但实际上线程池是如何添加线程,如何执行的呢?
0:创建线程池--略(7个参数)
1:提交线程池源码
public void execute(Runnable command) {
//判空没啥可说
if (command == null) throw new NullPointerException();
//获取核心属性
int c = ctl.get();
//workerCountOf(c)获取工作线程个数
//当前工作线程个数< 核心线程数
if (workerCountOf(c) < corePoolSize) {
//添加一个工作线程 true:核心线程 false:非核心线程
//添加工作线程有并发问题,若成功返回true,失败返回false
if (addWorker(command, true))
//成功,告辞~
return;
//添加失败,重新获取ctl,看一下当前线程情况
c = ctl.get();
}
// isRunning:线程池状态还是RUNNING嘛?
// 如果是RUNNING,就把任务扔到阻塞队列里,先排队等着
if (isRunning(c) && workQueue.offer(command)) {
//再次获取ct1属性
int recheck = ctl.get();
//再次确认线程池状态是否是RUNNING,如果不是RUNNING,将任务从阻塞队列移除
if (! isRunning(recheck) && remove(command))
//执行拒绝策略
reject(command);
//现在阻塞队列有任务,但是没有工作线程
else if (workerCountOf(recheck) == 0)
//创建一个非核心线程,去处理阻塞队列任务
addWorker(null, false);
}
// 如果任务没有扔到阻塞队列,添加非核心线程去处理任务
else if (!addWorker(command, false))
reject(command);
}
太简洁了,和我编程风格不习惯,本人优化一下,一毛一样的
//提交任务到线程池的方法
public void execute(Runnable command) {
//判空没啥可说
if (command == null) throw new NullPointerException();
//获取核心属性
int c = ctl.get();
//workerCountOf(c)获取工作线程个数
//当前工作线程个数< 核心线程数
if (workerCountOf(c) < corePoolSize) {
//添加一个工作线程 true:核心线程 false:非核心线程
//添加工作线程有并发问题,若成功返回true,失败返回false
if (addWorker(command, true)){
//成功,告辞~
return;
}
//添加失败,重新获取ctl,看一下当前线程情况
c = ctl.get();
}
// isRunning:线程池状态还是RUNNING嘛?
// 如果是RUNNING,就把任务扔到阻塞队列里,先排队等着
if (isRunning(c) && workQueue.offer(command)) {
//再次获取ct1属性
int recheck = ctl.get();
//再次确认线程池状态是否是RUNNING,如果不是RUNNING,将任务从阻塞队列移除
if (! isRunning(recheck) && remove(command)){
//执行拒绝策略
reject(command);
//现在阻塞队列有任务,但是没有工作线程
}else if (workerCountOf(recheck) == 0){
//创建一个非核心线程,去处理阻塞队列任务
addWorker(null, false);
}
//如果任务没有扔到阻塞队列,添加非核心线程去处理任务
}else if (!addWorker(command, false)){
reject(command);
}
}
好了,这回看着舒服多了,下面开始画流程图吧
2、流程图详解
3、添加工作线程的流程(addWorker方法)--后续添加