线程池(ThreadPoolExecutor)实现原理和源码细节是Java高并发面试和实战开发的重点
一、线程池核心流程图
+-----------------+
| 提交任务 | submit/execute
+-----------------+|v
+-----------------+
| 判断核心线程数 | < corePoolSize?
+-----------------+|Yes |Nov v
[创建新线程] +-----------------+| 队列是否满? |+-----------------+|No |Yesv v[入队列排队] +------------------+| 判断最大线程数 |+------------------+|No |Yesv v[创建新线程] [执行拒绝策略]
二、线程池主要环节及源码方法
1. 任务提交(execute/submit)
方法:
execute(Runnable command)
submit(Runnable/Callable)
源码片段:
public void execute(Runnable command) {if (command == null)throw new NullPointerException();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);
}
注释速记:
- 任务先尝试用核心线程处理。
- 核心线程满则尝试入队列。
- 队列满则尝试新建非核心线程。
- 实在不行,执行拒绝策略。
口诀:
先核心,后队列;队列满,再扩容;全满员,拒绝它。
2. 核心线程判断与创建
方法:
addWorker(Runnable firstTask, boolean core)
源码片段:
private boolean addWorker(Runnable firstTask, boolean core) {retry:for (;;) {int c = ctl.get();int rs = runStateOf(c);// ...省略状态判断for (;;) {int wc = workerCountOf(c);if (wc >= CAPACITY ||wc >= (core ? corePoolSize : maximumPoolSize))return false;if (compareAndIncrementWorkerCount(c))break retry;c = ctl.get();if (runStateOf(c) != rs)continue retry;}}// ...真正创建Worker线程
}
注释速记:
- 根据core参数决定是否用核心线程池大小。
- 用CAS增加线程计数,线程安全。
口诀:
核心先上,CAS抢位,线程安全,才创建。
3. 入队列
方法:
workQueue.offer(command)
源码片段:
if (isRunning(c) && workQueue.offer(command)) {// 入队成功后可能需要唤醒线程
}
注释速记:
- 队列没满则入队。
- 入队后如果线程都在忙,线程池不会立刻扩容。
口诀:
队列能放,直接排队。
4. 非核心线程扩容
逻辑:
- 当核心线程和队列都满时,允许创建新线程(最大线程数以内)。
源码片段:
else if (!addWorker(command, false))reject(command);
注释速记:
- 只有在核心线程和队列都满时才会扩容到最大线程数。
口诀:
满员排队,再扩容。
5. 拒绝策略
方法:
RejectedExecutionHandler.rejectedExecution(Runnable r, ThreadPoolExecutor e)
源码片段:
public static class AbortPolicy implements RejectedExecutionHandler {public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {throw new RejectedExecutionException();}
}
注释速记:
- 线程池和队列都满时,根据策略处理(抛异常/丢弃/调用者执行等)。
口诀:
全都满员,策略管。
6. 线程回收与销毁
方法:
worker.run()
- 判断空闲时间超过keepAliveTime
源码片段:
while (task != null || (task = getTask()) != null) {// 执行任务
}
注释速记:
- 非核心线程空闲时间到达后会被回收。
- 核心线程默认不会被回收(可通过allowCoreThreadTimeOut配置)。
口诀:
闲太久,自动走。
三、流程口诀速记
提任务,先核心,队列排,扩满员;全满员,策略管;空闲久,自动走。
四、常用方法与内部逻辑简表
阶段 | 关键方法/类 | 主要逻辑说明 |
---|---|---|
任务提交 | execute/submit | 任务进线程池 |
核心线程判断 | addWorker(core=true) | 核心线程是否有空位,有则新建 |
入队列 | workQueue.offer | 核心线程满,队列没满则排队 |
非核心线程 | addWorker(core=false) | 队列满,是否可新建非核心线程 |
拒绝策略 | RejectedExecutionHandler | 全部满员,执行拒绝策略 |
线程回收 | allowCoreThreadTimeOut | 非核心线程闲置超时自动销毁 |
五、源码脉络图(伪代码)
execute(command) {if (核心线程未满)addWorker(command, true) // 新核心线程else if (队列未满)workQueue.offer(command) // 入队列else if (线程池未满)addWorker(command, false) // 新非核心线程elsereject(command) // 拒绝策略
}
六、速记口诀总结
场景 | 口诀 |
---|---|
任务进池 | 先核心,后队列 |
队列满了 | 再扩容(到最大线程数) |
全满员 | 策略管(拒绝策略) |
线程回收 | 闲太久,自动走 |
全流程 | 提任务,先核心,队列排,扩满员;全满员,策略管;空闲久,自动走。 |
七、配图(流程图)
+-------------------------+| 提交任务 |+-------------------------+|+-------------+-------------+| |
+-----v-----+ +-----v-----+
| 核心线程? |----是-------->| 创建线程 |
+-----------+ +-----------+|否|
+-----v-----+
| 队列满? |----否-------> 入队列
+-----------+|是|
+-----v-----+
| 最大线程? |----否-------> 创建线程
+-----------+|是|
+-----v-----+
| 拒绝策略 |
+-----------+
八、结语
通过以上细化,线程池的工作原理、源码关键点、方法流程、口诀速记都一目了然。
只要记住口诀和流程图,结合源码细节,面试和实战都能轻松拿捏!
相关文章:
线程池(ThreadPoolExecutor)实现原理和源码细节是Java高并发面试和实战开发的重点
一、线程池核心流程图 ----------------- | 提交任务 | submit/execute -----------------|v ----------------- | 判断核心线程数 | < corePoolSize? -----------------|Yes |Nov v [创建新线程] -----------------| 队列是否满&a…...

MongoTemplate 基础使用帮助手册
前言 MongoDB 是一种流行的 NoSQL 数据库,适合存储大量的非结构化数据。MongoTemplate 是 Spring Data MongoDB 中的一个核心组件,它提供了一组丰富的 API 来与 MongoDB 进行交互。它封装了许多常见的数据库操作,使开发者能够轻松执行 CRUD 操…...

图像处理:预览并绘制图像细节
前言 因为最近在搞毕业论文的事情,要做出一下图像细节对比图,所以我这里写了两个脚本,一个用于框选并同时预览图像放大细节,可显示并返回框选图像的坐标,另外一个是输入框选图像的坐标并将放大的细节放置在图像中&…...

力扣热题——最长相邻不相等子序列 |
题目要求从字符串数组 words 中选出一个最长的子序列,使得该子序列中相邻字符串对应的 groups 数组中的值不同。通过贪心算法,可以高效地解决该问题。具体步骤为:初始化一个结果列表,遍历 words 数组,检查当前字符串的…...
【抽丝剥茧知识讲解】引入mybtis-plus后,mapper实现方式
目录 前言一、传统 Mapper 接口方式二、继承 BaseMapper 的方式三、自定义通用 Mapper 的方式四、使用 MyBatis-Plus 的 ActiveRecord 模式五、使用 MyBatis-Plus 的 IService 接口六、使用建议 前言 mapper文件,作为Mybatis框架中定义SQL语句和映射关系的配置文件&…...

ssti刷刷刷
[NewStarCTF 公开赛赛道]BabySSTI_One 测试发现过滤关键字,但是特殊符号中括号、双引号、点都能用 可以考虑拼接或者编码,这里使用拼接 ?name{{()["__cla"~"ss__"]}}?name{{()["__cla"~"ss__"]["__ba&…...

java+selenum专题(一)
环境搭建部署篇-> 1.简介 java版的selenium,介绍一下java selenium自动化测试。大致和pythonselenium自动化测试差不多。基于java和selenium做自动化测试,因此你必须会搭建基本的开发环境,掌握python基本的语法和一个IDE来进行开发&…...
物体雅克比、空间雅克比、解析雅克比、几何雅克比
在机器人学中,雅可比矩阵是连接广义坐标速度与末端执行器速度的关键工具。根据应用场景和参考系的不同,雅可比矩阵可分为物体雅可比(Body Jacobian)、空间雅可比(Space Jacobian)、解析雅可比(A…...

[逆向工程]DebugView捕获WPS日志?解析未运行WPS时Shell扩展加载的原因与解决方案(二十五)
[逆向工程]DebugView捕获WPS日志?解析未运行WPS时Shell扩展加载的原因与解决方案(二十五) 引言:一个“幽灵”般的日志问题 你是否在使用 DebugView 排查系统问题时,发现日志中频繁出现 WPS 相关模块(如 k…...

ACM模式用Scanner和System.out超时的解决方案和原理
Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 🌱🌱个人主页:奋斗的明志 🌱🌱所属专栏:笔试强训 📚本系列文章为个人学…...

Java注解详解:从入门到实战应用篇
1. 引言 Java注解(Annotation)是JDK 5.0引入的一种元数据机制,用于为代码提供附加信息。它广泛应用于框架开发、代码生成、编译检查等领域。本文将从基础到实战,全面解析Java注解的核心概念和使用场景。 2. 注解基础概念 2.1 什…...

QML 属性动画、行为动画与预定义动画
目录 引言相关阅读本文使用的动画属性工程结构示例解析示例1:属性动画应用示例2:行为动画实现示例3:预定义动画 总结工程下载 引言 QML动画系统为界面元素提供了流畅的过渡效果。本文通过三个示例,结合属性动画(PropertyAnimatio…...

window nvidia-smi命令 Failed to initialize NVML: Unknown Error
如果驱动目录下的可以执行,那可能版本原因 "C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi"复制"C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.exe"替换 C:\Windows\System32\nvidia-smi.exe 或者 把C:\Windows\System3…...

自学嵌入式 day19-数据结构 链表
二、线性表的链式存储 1.特点: (1)线性表链式存储结构的特点是一组任意的存储单位存储线性表的数据元素,存储单元可以是连续的,也可以不连续。可以被存储在任意内存未被占用的位置上。 (2)所以…...

东芝第3代SiC MOSFET助于降低应用中电源损耗
功率器件是管理和降低各种电子设备电能功耗以及实现碳中和社会的重要元器件。由于与比硅材料相比,碳化硅具有更高的电压和更低的损耗,因此碳化硅(SiC)被广泛视为下一代功率器件的材料。虽然碳化硅功率器件目前主要用于列车逆变器&…...
Vue 2.0学习
个人简介 👨💻个人主页: 魔术师 📖学习方向: 主攻前端方向,正逐渐往全栈发展 🚴个人状态: 研发工程师,现效力于政务服务网事业 🇨🇳人生格言&…...
Mendix 中的XPath 令牌(XPath Tokens)详解
在 Mendix 中,XPath 令牌(XPath Tokens) 是一种特殊的动态参数化查询技术,允许你在 XPath 表达式中使用变量或上下文相关的值,从而实现更灵活的查询逻辑。 1. 什么是 XPath 令牌? XPath 令牌是 Mendix 提…...
Spring Batch学习,和Spring Cloud Stream区别
Spring Batch学习,和Spring Cloud Stream区别 1. 使用Spring Initializr创建项目2. 使用步骤构建作业(Chunk 模式)🧩 场景说明🧰 1. 示例目录结构📄 2. 创建输入文件(users.csv)&…...
【技术原理】Linux 文件时间属性详解:Access、Modify、Change 的区别与联系
在 Linux 系统中,每个文件都有三个核心时间属性:Access Time (atime)、Modify Time (mtime) 和 Change Time (ctime)。它们分别记录文件不同维度的变更信息,以下是具体区别与联系: 一、定义与触发条件 时间属性定义触发条件示例A…...
k8s之LoadBalancer Service 解析
Kubernetes LoadBalancer Service 解析:IP与端口详解 服务类型与IP解析 Service 是 Kubernetes 中的资源类型,用来将一组 Pod 的应用作为网络服务公开。每个 Pod 都有自己的 IP,但是这个 IP 的生命周期与 Pod 生命周期一致,也就…...
Vue3项目使用ElDrawer后select方法不生效
Vue3 项目中 ElDrawer 内 ElSelect 下拉框 z-index 失效问题分析与解决方案 问题描述问题分析解决方案结论 问题描述 在 Vue3 项目中使用 Element Plus 的 ElDrawer 组件时,当在抽屉内部使用 ElSelect 组件,发现下拉选择框(dropdownÿ…...

PD 分离推理的加速大招,百度智能云网络基础设施和通信组件的优化实践
为了适应 PD 分离式推理部署架构,百度智能云从物理网络层面的「4us 端到端低时延」HPN 集群建设,到网络流量层面的设备配置和管理,再到通信组件和算子层面的优化,显著提升了上层推理服务的整体性能。 百度智能云在大规模 PD 分离…...

官方 Elasticsearch SQL NLPChina Elasticsearch SQL
官方的可以在kibana 控制台上进行查询: POST /_sql { “query”: “SELECT client_ip, status FROM logs-2024-05 WHERE status 500” } NLPChina Elasticsearch SQL就无法以在kibana 控制台上进行查询,但是可以使用postman接口进行查询:...

5月16日复盘-目标检测开端
5月16日复盘 一、图像处理之目标检测 1. 目标检测认知 Object Detection,是指在给定的图像或视频中检测出目标物体在图像中的位置和大小,并进行分类或识别等相关任务。 目标检测将目标的分割和识别合二为一。 What、Where 2. 使用场景 目标检测用于…...
读取toml, 合并,生成新文件
依次读取三个TOML文件并合并,后续文件覆盖之前的值,最终将结果写入新文件 import toml def deep_update(base_dict, update_dict): """ 递归合并字典,后续字典的值覆盖前者[6] """ for key, …...

mathematics-2024《Graph Convolutional Network for Image Restoration: A Survey》
推荐深蓝学院的《深度神经网络加速:cuDNN 与 TensorRT》,课程面向就业,细致讲解CUDA运算的理论支撑与实践,学完可以系统化掌握CUDA基础编程知识以及TensorRT实战,并且能够利用GPU开发高性能、高并发的软件系统…...

IDEA怎么汉化idea中文改回英文版
第一步:点击左上角的File,然后选择Setting 第二步:Setting页面选择 Appearance & Behavior,然后展开System Settings,然后选择 Language and Region,进行修改 我操作的是2024年的版本 File->Settings -> Ap…...
Android minSdk从21升级24后SO库异常
问题 minSdk从21调整到24后: java.nio.file.NoSuchFileException: /data/app/~~Z9s2NfuDdclOUwUBLKnk0A/com.rs.unity- Bg31QvFwF4qsCwv2XCqT-w/split_config.arm64_v8a.apkjava.nio.file.NoSuchFileException: /data/app/~~Z9s2NfuDdclOUwUBLKnk0A/com.rs.unity-…...

车道线检测----CLRKDNet
今天的最后一篇 车道线检测系列结束 CLRKDNet:通过知识蒸馏加速车道检测 摘要:道路车道是智能车辆视觉感知系统的重要组成部分,在安全导航中发挥着关键作用。在车道检测任务中,平衡精度与实时性能至关重要,但现有方法…...

从技术视角解构 Solana Meme 币生态
在高吞吐、高并发的 Solana 网络上,一类轻量化、高热度的代币形式正在爆发式增长——Meme Token(迷因代币)。尽管起源于社群文化,但其技术实现并非“玩笑”,而是一整套构建于 Solana Runtime 与 Token Extensions 之上…...