当前位置:网站首页>Thread pool execution process
Thread pool execution process
2022-06-24 10:24:00 【Ugly and ugly】

If shown in , Is the execution process of the thread pool , It can be divided into three main steps :
1. After the task is submitted, the current number of worker threads will be compared with the number of core threads , If the current number of worker threads is less than the number of core threads , Call directly addWorker() Method to create a core thread to execute tasks ;
2. If the number of worker threads is greater than the number of core threads , That is, the number of core threads in the thread pool is full , The new task will be added to the blocking queue for execution , Of course , Before adding a queue, you will also judge whether the queue is empty ;
3. If the number of surviving threads in the thread pool is equal to the number of core threads , And the blocking queue is full , Then you will judge whether the current number of threads has reached the maximum number of threads maximumPoolSize, If not , It will call addWorker() Method to create a non core thread to execute the task ;
4. If the current number of threads has reached the maximum number of threads , When a new task is submitted , Will execute a rejection strategy
In conclusion, it is Priority core threads 、 Blocking queue takes second place , Finally, non core threads .
java.util.concurrent.ThreadPoolExecutor#execute The source code of is :
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);
}You can see , The comments in the source code also explain the whole excute() Method can be executed in three steps .
Variable in source code ctl It's an atomic class , The main function is to save the number of threads and the state of thread pool . Here we use high 3 Bit to save the running state , low 29 Bits to save the number of threads .
In these steps , The most important thing is addWorker() The method .
private boolean addWorker(Runnable firstTask, boolean core);The first parameter represents the task to be executed , If null, Then pull the task from the blocking queue ;
The second parameter indicates whether it is a core thread , Used to control addWorker() The process of .
addWorker() The main implementation process of the method is :

The source code is :
private boolean addWorker(Runnable firstTas
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if nec
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize
return false;
if (compareAndIncrementWorkerCo
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to worke
}
}
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 =
mainLock.lock();
try {
// Recheck while holding lo
// Back out on ThreadFactor
// shut down before lock ac
int rs = runStateOf(ctl.get
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firs
if (t.isAlive()) // pre
throw new IllegalTh
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)
addWorkerFailed(w);
}
return workerStarted;
}addWorker() It will be used repeatedly during execution runStateOf() and workerCountOf() To get the status of the thread pool and the number of worker threads .
This article references from : Three minutes to understand the thread pool execution process - Nuggets
边栏推荐
猜你喜欢
随机推荐
leetCode-面试题 16.06: 最小差
分布式 | 如何与 DBLE 进行“秘密通话”
How can I solve the problem that the swiper animation animation fails when switching between left and right rotations of the swiper?
5.菜品管理业务开发
静态链接库和动态链接库的区别
学习使用KindEditor富文本编辑器,点击上传图片遮罩太大或白屏解决方案
Machine learning - principal component analysis (PCA)
一群骷髅在飞canvas动画js特效
学习整理在php中使用KindEditor富文本编辑器
Role of message queuing
使用swiper左右轮播切换时,Swiper Animate的动画失效,怎么解决?
Leetcode-1089: replication zero
用扫描的方法分发书稿校样
1. project environment construction
形状变化loader加载jsjs特效代码
卷妹带你学jdbc---2天冲刺Day1
canvas无限扫描js特效代码
【IEEE出版】2022年服务机器人国际研讨会(IWoSR 2022)
Uniapp implementation forbids video drag fast forward
JMeter接口测试工具基础 — Badboy工具








