线程池(ThreadPoolExecutor)实现原理和源码细节是Java高并发面试和实战开发的重点

news2025/5/17 13:05:10

一、线程池核心流程图

+-----------------+
|    提交任务      | submit/execute
+-----------------+
         |
         v
+-----------------+
| 判断核心线程数  | < corePoolSize?
+-----------------+
   |Yes        |No
   v           v
[创建新线程]   +-----------------+
              | 队列是否满?     |
              +-----------------+
                  |No        |Yes
                  v           v
            [入队列排队]   +------------------+
                           | 判断最大线程数  |
                           +------------------+
                              |No          |Yes
                              v             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) // 新非核心线程
    else
        reject(command)           // 拒绝策略
}

六、速记口诀总结

场景口诀
任务进池先核心,后队列
队列满了再扩容(到最大线程数)
全满员策略管(拒绝策略)
线程回收闲太久,自动走
全流程提任务,先核心,队列排,扩满员;全满员,策略管;空闲久,自动走。

七、配图(流程图)

         +-------------------------+
         |      提交任务           |
         +-------------------------+
                    |
      +-------------+-------------+
      |                           |
+-----v-----+               +-----v-----+
| 核心线程? |----是-------->| 创建线程  |
+-----------+               +-----------+
      |
      否
      |
+-----v-----+
| 队列满?   |----否-------> 入队列
+-----------+
      |
      是
      |
+-----v-----+
| 最大线程? |----否-------> 创建线程
+-----------+
      |
      是
      |
+-----v-----+
| 拒绝策略  |
+-----------+

八、结语

通过以上细化,线程池的工作原理、源码关键点、方法流程、口诀速记都一目了然。
只要记住口诀和流程图,结合源码细节,面试和实战都能轻松拿捏!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2377680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MongoTemplate 基础使用帮助手册

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

图像处理:预览并绘制图像细节

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

力扣热题——最长相邻不相等子序列 |

题目要求从字符串数组 words 中选出一个最长的子序列&#xff0c;使得该子序列中相邻字符串对应的 groups 数组中的值不同。通过贪心算法&#xff0c;可以高效地解决该问题。具体步骤为&#xff1a;初始化一个结果列表&#xff0c;遍历 words 数组&#xff0c;检查当前字符串的…

ssti刷刷刷

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

java+selenum专题(一)

环境搭建部署篇-> 1.简介 java版的selenium&#xff0c;介绍一下java selenium自动化测试。大致和pythonselenium自动化测试差不多。基于java和selenium做自动化测试&#xff0c;因此你必须会搭建基本的开发环境&#xff0c;掌握python基本的语法和一个IDE来进行开发&…

[逆向工程]DebugView捕获WPS日志?解析未运行WPS时Shell扩展加载的原因与解决方案(二十五)

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

ACM模式用Scanner和System.out超时的解决方案和原理

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;笔试强训 &#x1f4da;本系列文章为个人学…

Java注解详解:从入门到实战应用篇

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

QML 属性动画、行为动画与预定义动画

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

window nvidia-smi命令 Failed to initialize NVML: Unknown Error

如果驱动目录下的可以执行&#xff0c;那可能版本原因 "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.特点&#xff1a; &#xff08;1&#xff09;线性表链式存储结构的特点是一组任意的存储单位存储线性表的数据元素&#xff0c;存储单元可以是连续的&#xff0c;也可以不连续。可以被存储在任意内存未被占用的位置上。 &#xff08;2&#xff09;所以…

东芝第3代SiC MOSFET助于降低应用中电源损耗

功率器件是管理和降低各种电子设备电能功耗以及实现碳中和社会的重要元器件。由于与比硅材料相比&#xff0c;碳化硅具有更高的电压和更低的损耗&#xff0c;因此碳化硅&#xff08;SiC&#xff09;被广泛视为下一代功率器件的材料。虽然碳化硅功率器件目前主要用于列车逆变器&…

PD 分离推理的加速大招,百度智能云网络基础设施和通信组件的优化实践

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

官方 Elasticsearch SQL NLPChina Elasticsearch SQL

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

5月16日复盘-目标检测开端

5月16日复盘 一、图像处理之目标检测 1. 目标检测认知 ​ Object Detection&#xff0c;是指在给定的图像或视频中检测出目标物体在图像中的位置和大小,并进行分类或识别等相关任务。 ​ 目标检测将目标的分割和识别合二为一。 ​ What、Where 2. 使用场景 目标检测用于…

mathematics-2024《Graph Convolutional Network for Image Restoration: A Survey》

推荐深蓝学院的《深度神经网络加速&#xff1a;cuDNN 与 TensorRT》&#xff0c;课程面向就业&#xff0c;细致讲解CUDA运算的理论支撑与实践&#xff0c;学完可以系统化掌握CUDA基础编程知识以及TensorRT实战&#xff0c;并且能够利用GPU开发高性能、高并发的软件系统&#xf…

IDEA怎么汉化idea中文改回英文版

第一步:点击左上角的File&#xff0c;然后选择Setting 第二步&#xff1a;Setting页面选择 Appearance & Behavior&#xff0c;然后展开System Settings&#xff0c;然后选择 Language and Region&#xff0c;进行修改 我操作的是2024年的版本 File->Settings -> Ap…

车道线检测----CLRKDNet

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

从技术视角解构 Solana Meme 币生态

在高吞吐、高并发的 Solana 网络上&#xff0c;一类轻量化、高热度的代币形式正在爆发式增长——Meme Token&#xff08;迷因代币&#xff09;。尽管起源于社群文化&#xff0c;但其技术实现并非“玩笑”&#xff0c;而是一整套构建于 Solana Runtime 与 Token Extensions 之上…

智能接处警系统:以秒级联动响应重塑应急处置效能

​​随着我国能源、化工、航空等关键行业的快速发展&#xff0c;传统消防管理模式已难以满足高效应急响应的需求。国家能源局、应急管理部、民航总局均出台专项规定&#xff0c;对消防站建设提出更高要求&#xff0c;在此背景下&#xff0c;智能接处警系统正是应对这些挑战的核…