当前位置:网站首页>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
边栏推荐
猜你喜欢

1.项目环境搭建

Machine learning - principal component analysis (PCA)

2.登陆退出功能开发

记录一下MySql update会锁定哪些范围的数据

JMeter接口测试工具基础— 取样器sampler(二)

p5.js实现的炫酷交互式动画js特效

Go language development environment setup +goland configuration under the latest Windows

2022年智能机器人与系统国际研讨会(ISoIRS 2022)

Uniapp implements the function of clicking to make a call

利用pandas读取SQL Sever数据表
随机推荐
分布式 | 如何与 DBLE 进行“秘密通话”
Using pandas to read SQL server data table
涂鸦智能携多款重磅智能照明解决方案,亮相2022美国国际照明展
uniapp实现点击拨打电话功能
[EI分享] 2022年第六届船舶,海洋与海事工程国际会议(NAOME 2022)
SQL sever试题求最晚入职日期
Distributed | how to make "secret calls" with dble
np. float32()
Leetcode interview question 01.05: primary editing
线程的 sleep() 方法与 wait() 方法的区别
卷妹带你学jdbc---2天冲刺Day1
Common methods of thread scheduling
形状变化loader加载jsjs特效代码
学习整理在php中使用KindEditor富文本编辑器
美国电子烟巨头 Juul 遭遇灭顶之灾,所有产品强制下架
植物生长h5动画js特效
web网站开发,图片懒加载
【Energy Reports期刊发表】2022年能源与环境工程国际会议(CFEEE 2022)
tf.contrib.layers.batch_norm
leetCode-1051: 高度检查器