当前位置:网站首页>线程池的执行流程
线程池的执行流程
2022-06-24 09:43:00 【文丑颜不良啊】

如果所示,就是线程池的执行过程,可以分为三个主要步骤:
1.提交任务后会首先进行当前工作线程数与核心线程数的比较,如果当前工作线程数小于核心线程数,则直接调用 addWorker() 方法创建一个核心线程去执行任务;
2.如果工作线程数大于核心线程数,即线程池核心线程数已满,则新任务会被添加到阻塞队列中等待执行,当然,添加队列之前也会进行队列是否为空的判断;
3.如果线程池里面存活的线程数已经等于核心线程数了,且阻塞队列已经满了,再会去判断当前线程数是否已经达到最大线程数 maximumPoolSize,如果没有达到,则会调用 addWorker() 方法创建一个非核心线程去执行任务;
4.如果当前线程的数量已经达到了最大线程数时,当有新的任务提交过来时,会执行拒绝策略
总结来说就是优先核心线程、阻塞队列次之,最后非核心线程。
java.util.concurrent.ThreadPoolExecutor#execute 的源码为:
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);
}可以看到,源码中的注释部分也说明了整个 excute() 方法的执行过程可分为三个步骤。
源码中变量 ctl 是一个原子类,主要作用是用来保存线程数量和线程池的状态。这里采用高 3 位来保存运行状态,低 29 位来保存线程数量。
在这几个步骤中,最重要的当属 addWorker() 方法了。
private boolean addWorker(Runnable firstTask, boolean core);第一个参数表示要执行的任务,如果为 null,则从阻塞队列中拉取任务;
第二个参数表示是否是核心线程,用来控制 addWorker() 的流程。
addWorker() 方法的实现主流程为:

源码为:
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() 执行过程中会反复使用 runStateOf() 和 workerCountOf() 来获取线程池的状态和工作线程的数量。
本文参考自:三分钟弄懂线程池执行过程 - 掘金
边栏推荐
- Operator details
- Thinkphp5 clear the cache cache, temp cache and log cache under runtime
- How to standardize data center infrastructure management process
- How to improve the efficiency of network infrastructure troubleshooting and bid farewell to data blackouts?
- Analysis of 43 cases of MATLAB neural network: Chapter 32 time series prediction of wavelet neural network - short-term traffic flow prediction
- Is there a reliable and low commission futures account opening channel in China? Is it safe to open an account online?
- 整理接口性能优化技巧,干掉慢代码
- Impdp leading schema message ora-31625 exception handling
- Regular matching mailbox
- Distributed | how to make "secret calls" with dble
猜你喜欢

canvas 绘制图片

Top issue tpami 2022! Behavior recognition based on different data modes: a recent review

canvas无限扫描js特效代码

Record the range of data that MySQL update will lock

Use of vim

Practical analysis: implementation principle of APP scanning code landing (app+ detailed logic on the web side) with source code

机器学习——主成分分析(PCA)

Development of anti fleeing marketing software for health products

CVPR 2022 Oral | 英伟达提出自适应token的高效视觉Transformer网络A-ViT,不重要的token可以提前停止计算

Getting user information for applet learning (getuserprofile and getUserInfo)
随机推荐
numpy.logical_or
H5网页如何在微信中自定义分享链接
port 22: Connection refused
学习使用KindEditor富文本编辑器,点击上传图片遮罩太大或白屏解决方案
Juul, the American e-cigarette giant, suffered a disaster, and all products were forced off the shelves
How to standardize data center infrastructure management process
NVIDIA's CVPR 2022 oral is on fire! 2D images become realistic 3D objects in seconds! Here comes the virtual jazz band!
Analysis of 43 cases of MATLAB neural network: Chapter 32 time series prediction of wavelet neural network - short-term traffic flow prediction
PostgreSQL DBA quick start - source compilation and installation
Safety and food security for teachers and students of the trapped Yingxi middle school
Regular matching mobile number
上升的气泡canvas破碎动画js特效
时尚的弹出模态登录注册窗口
利用pandas读取SQL Sever数据表
Machine learning - principal component analysis (PCA)
Engine localization adaptation & Reconstruction notes
Graffiti smart brings a variety of heavy smart lighting solutions to the 2022 American International Lighting Exhibition
Amendment to VPP implementation policy routing
[input method] so far, there are so many Chinese character input methods!
解决微信小程序rich-text富文本标签内部图片宽高自适应的方法