ThreadPoolExecutor 最佳实践

ThreadPoolExecutor最佳实践--如何选择线程数 去年的一篇《ThreadPoolExecutor详解》大致讲了ThreadPoolExecutor内部的代码实现。 总结一下,主要有以下四点: 当有任务提交的时候,会创建核心线程去执行任务; 当核心线程数达到corePoolSize时,后续提交的都会进BlockingQueue中排队; 当BlockingQueue满了(offer失败),就回创建临时线程; 当线程总数达到maximumPoo... 阅读详情

1. 基本定位

ThreadPoolExecutor 是 Java 并发包核心线程池实现,管理线程生命周期和任务调度,主要解决:

  • 线程复用(减少频繁创建销毁线程的开销)

  • 任务调度(控制并发度、任务队列、拒绝策略)

  • 资源隔离(不同任务用不同线程池,避免互相阻塞)

它实现了:

  • Executor(任务执行接口)

  • ExecutorService(任务提交/关闭接口)

  • 支持生命周期管理(shutdown、shutdownNow)

  • 内置任务统计与监控 API


2. 构造方法与参数详解

public ThreadPoolExecutor(
    int corePoolSize,                // 核心线程数
    int maximumPoolSize,             // 最大线程数
    long keepAliveTime,               // 非核心线程空闲回收时间
    TimeUnit unit,                    // 时间单位
    BlockingQueue<Runnable> workQueue,// 任务队列
    ThreadFactory threadFactory,      // 线程工厂
    RejectedExecutionHandler handler  // 拒绝策略
)
参数含义核心作用调优建议
corePoolSize核心线程数常驻执行任务的线程数(默认不回收)CPU 密集型 = CPU 核数+1;IO 密集型 = CPU 核数 × 2~4
maximumPoolSize最大线程数峰值时可扩容到的线程数有界队列下才有意义
keepAliveTime空闲时间非核心线程的回收时间流量波动大时调短,减少空闲线程占用
unit时间单位keepAliveTime 的单位常用 SECONDS
workQueue任务队列决定任务缓冲与调度策略有界队列防 OOM
threadFactory线程工厂线程命名、优先级、守护状态建议自定义,方便排查
handler拒绝策略队列与线程均满时的处理逻辑核心任务用 CallerRunsPolicy


3. 执行流程(源码级)

调用 execute(Runnable) 时,流程如下:

  1. 核心线程不足
    → 直接创建新线程执行任务(addWorker(command, true))

  2. 核心线程已满
    → 尝试放入任务队列(workQueue.offer(command))

  3. 队列已满
    → 尝试创建非核心线程(addWorker(command, false))

  4. 非核心线程已满
    → 执行拒绝策略(handler.reject())

源码关键片段:

 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);
    }


    private static int runStateOf(int c)     { return c & ~COUNT_MASK; }
    private static int workerCountOf(int c)  { return c & COUNT_MASK; }

4. 内部核心结构

4.1 ctl(线程池状态 + 线程数)

  • 高 3 位表示线程池状态(RUNNING/SHUTDOWN/STOP/TIDYING/TERMINATED)

  • 低 29 位表示当前线程数

4.2 Worker(工作线程)

  • ThreadPoolExecutor.Worker 继承 AQS,封装了线程对象和首个任务

  • 持有独占锁,防止在执行任务时被错误中断

4.3 getTask()(任务获取逻辑)

  • 核心线程:queue.take()(阻塞等待)

  • 非核心线程:queue.poll(keepAliveTime)(超时等待,超时回收)


5. 常用任务队列类型

队列类型是否有界特点适用场景
SynchronousQueue容量=0任务直接交给线程,不排队高并发短任务
LinkedBlockingQueue默认无界可缓冲大量任务,FIFO低风险流量,需指定容量
ArrayBlockingQueue有界固定容量,FIFO内存可控,高峰可触发扩容
PriorityBlockingQueue默认无界按优先级执行调度系统
DelayQueue默认无界延迟任务队列定时任务


6. 拒绝策略(RejectedExecutionHandler)

  1. AbortPolicy(默认) → 抛异常

  2. CallerRunsPolicy → 调用方线程执行任务

  3. DiscardPolicy → 直接丢弃

  4. DiscardOldestPolicy → 丢弃最老任务,重试入队

生产建议:

  • 核心业务:CallerRunsPolicy + 日志告警

  • 非关键业务:DiscardPolicy


7. 最佳实践配置

7.1 CPU 密集型任务

new ThreadPoolExecutor(
    Runtime.getRuntime().availableProcessors() + 1,
    Runtime.getRuntime().availableProcessors() + 1,
    0L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(1000),
    threadFactory,
    new ThreadPoolExecutor.CallerRunsPolicy()
);

7.2 IO 密集型任务

new ThreadPoolExecutor(
    cpu * 2,
    cpu * 4,
    60L, TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(2000),
    threadFactory,
    new ThreadPoolExecutor.CallerRunsPolicy()
);

7.3 流量波动场景(核心线程可回收)

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    4, 20,
    60L, TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(500),
    threadFactory
);
executor.allowCoreThreadTimeOut(true);

8. 调优要点

  1. 避免无界队列(LinkedBlockingQueue 默认无界 → maximumPoolSize 失效)

  2. 与容器资源绑定

    • corePoolSize ≈ CPU Limit

    • 避免超配导致 CPU 抢占

  3. 监控指标

    • activeCount / poolSize / queue.size()

    • completedTaskCount

  4. 优雅停机

    • @PreDestroy (spring)调用 shutdown() + awaitTermination

  5. 隔离不同业务

    • 核心业务与非核心业务用不同线程池

  6. 拒绝策略监控

    • 自定义 handler 记录拒绝任务日志


9. 常见误区

  • newFixedThreadPool + LinkedBlockingQueue 默认无界 → OOM

  • keepAliveTime=0 且不 allowCoreThreadTimeOut → 核心线程常驻浪费资源

  • 无界队列下 maximumPoolSize 无效

  • 任务执行时间过长 → 队列堆积,延迟高

  • 线程池被 Spring 代理关闭 → 任务丢失(需显式 @Bean(destroyMethod="shutdown"))

ThreadPoolExecutor源码解读(二),Java性能优化最佳实践 虽然我个人也经常自嘲,十年之后要去成为外卖专员,但实际上依靠自身的努力,是能够减少三十五岁之后的焦虑的,毕竟好的架构师并不多。架构师,是我们大部分技术人的职业目标,一名好的架构师来源于机遇(公司)、个人努力(吃得苦、肯钻研)、天分(真的热爱)的三者协作的结果,实践+机遇+努力才能助你成为优秀的架构师。如果你也想成为一名好的架构师,那或许这份Java成长笔记你需要阅读阅读,希望能够对你的职业发展有所帮助。[外链图片转存中…(img-b9CpaWFw-1711087210715)] 阅读详情

相关推荐

独立游戏开发者的新武器:实测腾讯混元3D自动绑骨,搭配Mixamo让角色动画制作效率翻倍

本文实测腾讯混元3D自动绑骨功能与Mixamo动画库的协同使用,显著提升独立游戏开发者的角色动画制作效率。通过解决卡通角色绑骨偏差、优化骨骼权重及动画状态机配置,使原本两周的流程缩短至三天,并分享Unity中的性能优化与版权合规要点。

weixin_42662605的博客 488

ThreadPoolExecutor里的参数如何配置可以达到效率最大化

keepAliveTime:非核心线程闲置超时时间,即当线程池中的线程数大于corePoolSize时,多余的线程在等待新任务时的最长等待时间,超过该时间后将被回收。maximumPoolSize:线程池最大线程数,这里的线程数并不包括核心线程数。corePoolSize:核心线程数,表示在没有任务需要执行的情况下,线程池中的线程数目。通过自定义线程工厂,可以为线程池创建自定义线程类实例。根据具体的应用场景,上述参数的配置可以根据硬件环境和任务特点等因素进行调整,以达到线程池效率的最大化。

Javachengye的专栏 2031

从FOC到你的无人机:深入浅出讲透Clark/Park变换在无刷电机控制中的核心作用

本文深入解析Clark变换与Park变换在无刷电机控制中的核心作用,揭示其如何将三相交流电转换为旋转坐标系下的直流量,实现无人机电机的高效精准控制。通过STM32硬件加速和工程实践案例,展示这对数学变换如何成为FOC算法的神经中枢,大幅提升系统响应速度和能效表现。

weixin_42628941的博客 167

ThreadPoolTaskExecutor线程池参数配置

一、线程池配置 1、ThreadPoolConfig import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.Threa

Thinkingcao的专栏 1万+

保姆级教程:在Ubuntu 22.04上,用Chroot和xorriso定制你的专属服务器镜像(附离线包集成)

本文提供了一份详细的Ubuntu 22.04离线镜像定制教程,通过Chroot环境和xorriso工具,帮助用户打造专属服务器镜像。教程涵盖环境准备、镜像解构、系统定制、镜像重组与验证等全流程,特别适合需要在隔离网络环境中批量部署服务器的场景。

weixin_28704565的博客 442

(12)单相降压自耦变压器的等效电路和仿真模型

本文根据电机学基本原理,从单相双绕组变压器的接线方式出发,建立基本方程并导出T型等效电路。然后将双绕组变压器演变成一种降压自耦变压器,详细地建立起单相降压自耦变压器的数学模型以及导出相对应的等效电路,最后用Matlab/simulink的simscape元件库元件建立了基于单相自耦变压器的T型等效电路的仿真模型。用实例仿真验证了本文工作的正确性。

weixin_45670943的博客 1046

线程池的参数及执行顺序

线程池的优点 降低系统资源消耗 提高系统响应速度 方便线程并发数的管控

杨幂等 1913

【微电网优化】基于粒子群求解CHP机组、气网、电网、储热罐和电锅炉微电网优化模型附matlab代码

1 简介 我国风力发电近年发展迅速,装机容量已成为全球首位.随着风力发电在电力系统中的渗透率不断提高,我国多个地区(尤其是"三北"地区)已经面临着十分严峻的风电消纳问题,产生不容忽视的弃风问题.针对目前我国风电消纳存在的困难,本文提出粒子群优化CHP机组、气网、电网、储热罐和电锅炉微电网控制策略. 2 部分代码 Ppv=[0;0;0;0;0;0;9.86000000000000;19.0100000000000;33.1000000000000;45.0700000000000;64.7900000

qq_59747472的博客 671

线程池ThreadPoolExecutor参数设置

JDK1.5中引入了强大的concurrent包,其中最常用的莫过了线程池的实现ThreadPoolExecutor,它给我们带来了极大的方便,但同时,对于该线程池不恰当的设置也可能使其效率并不能达到预期的效果,甚至仅相当于或低于单线程的效率。 ThreadPoolExecutor类可设置的参数主要有: corePoolSize 核心线程数,核心线程会一直存活,即使没有任务需

周宏亮G的日志 9万+

Nature Communications|马兰戈尼效应构建空心金字塔微阵列制备高灵敏度柔性电容式压力传感器(健康监测/柔性压力传感/柔性电子/人机交互)

三维(3D)微结构因其在柔软性、轻质化、对3D表面的贴合性和可压缩性方面的显著优势,已经在生物医学监测、人机接口、机器人触觉和微型飞行器等领域引起了广泛关注。柔性电容式压力传感器(CPSs),由两片平行板组成,中间夹着一层软介电薄膜,具有设备构造简单、高灵敏度和快速响应速度等众多吸引人的优点。结构化介电层的三维机械设计在决定传感器性能方面起着至关重要的作用,如灵敏度(这是压力传感器的关键特性,因为它决定了感知微小压力和获取更多细节的能力,如轻柔触摸和脉搏检测)。

感知科学前沿 526

STM32cubemx配置驱动DHT11模块

本篇文章将带大家学习使用DHT11湿温度模块,使用这个模块可以获取当前的温度和湿度数据。DHT11可以用于智能家居,蔬菜大棚等项目当中适用范围广。DHT11 是一种数字式温湿度传感器,由杜邦公司推出。它可以测量环境中的温度和湿度,并将测量结果以数字形式传输给微控制器或其他电子设备,适用于通过数字信号读取环境温湿度的应用场景。DHT11 传感器使用单总线数据交换协议,可以通过一个 I/O 引脚进行控制和数据传输。

m0_49476241的博客 5912

浅谈ThreadPoolTaskExeuctor配置

章节目录概念配置说明总结 概念 配置说明 总结

MuskMelon 597

不会精准对比前人研究写“讨论与对比”段落?教你用ChatGPT辅助,直接让这部分提升一个档次(附提示词指令)

一个我觉得很有效的做法是,选取几篇具有代表性的文献,从研究方法、变量设置或结论方面进行对照分析,并指出本研究在哪些方面进行了补充或修正。除了简单说“提出了新的方法”或“首次应用某模型”,更需要说明这一做法在结果解读、研究设计或理论拓展上的具体意义,最好能够与现有研究进行比较,形成明确的差异化描述。段落应包含:研究结果解释、与前人研究对比、研究贡献、局限性反思,并在结尾提出未来研究的可能方向。讨论与对比部分一般位于文献综述、研究讨论或结果分析的后面,目的是对比已有研究,突出自己研究的价值与新意。

智能AI让学术科研更容易 169

ThreadPoolExecutor 使用最佳实践

摘要:CompletableFuture使用默认线程池ForkJoinPool.commonPool()存在资源竞争、无法定制等问题。建议创建专用线程池,并通过supplyAsync/thenApplyAsync等方法指定执行线程池。最佳实践包括:线程池隔离(不同业务使用独立线程池)、异常处理、超时控制、资源清理和线程池监控。同时应注意在应用关闭时正确关闭线程池,并通过监控指标进行调优。这些措施能有效提升异步任务执行的可靠性和性能。

★【World Of Moshow 郑锴】★ 271

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

JAVA线程池ThreadPoolExecutor拒绝策略深度解析与最佳实践

ThreadPoolExecutor拒绝策略解析:文章详细介绍了线程池的四种内置拒绝策略(AbortPolicy、CallerRunsPolicy、DiscardPolicy、DiscardOldestPolicy)及其适用场景,并提供了自定义策略的最佳实践,包括日志记录、重试、降级和监控等方案。针对不同业务场景(电商订单、实时数据流、API网关)给出了具体实现建议,强调拒绝策略需结合业务优先级、系统资源和监控体系进行设计。核心原则是关键业务不能丢、非关键业务合理降级,所有拒绝都应可监控追溯。

★【World Of Moshow 郑锴】★ 1347

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Java线程池深入剖析ThreadPoolExecutor的工作原理与最佳实践

在Java多线程编程中,线程池是一种基于池化思想管理线程的工具。频繁地创建和销毁线程会消耗大量系统资源,并带来巨大的性能开销。ThreadPoolExecutor作为Java并发包java.util.concurrent中的核心类,提供了一个强大且灵活的可扩展线程池实现。它通过预先创建一定数量的线程并复用它们来执行大量异步任务,从而减少了线程创建和销毁的开销,提高了系统的响应速度,并且提供了丰富的钩子方法和配置参数,允许开发者根据实际应用场景进行精细调控,是构建高性能、高并发应用的关键组件。

gao738508的博客 385

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

ThreadPoolExecutor最佳实践--如何选择队列

前一篇文章《如何选择线程数》讲了如何决定线程池中线程个数,这篇文章讨论“如何选择工作队列”。 再次强调一下,ThreadPoolExecutor最核心的四点: 1、当有任务提交的时候,会创建核心线程去执行任务(即使有核心线程空闲); 2、当核心线程数达到corePoolSize时,后续提交的都会进BlockingQueue中排队; 3、当BlockingQueue满了(offer失败),就...

优快云文章已停止维护,后续文章会在 https://blog.hufeifei.cn 持续更新 6591

ThreadPoolExecutor回调陷阱揭秘:你所不知道的10个坑及最佳实践

揭秘ThreadPoolExecutor的完成回调陷阱,提供10个常见问题的解决方案与最佳实践。涵盖Future回调、线程安全、异常处理等核心机制,适用于高并发任务监控与结果处理场景,提升程序稳定性与响应效率,值得收藏。

ProceNest的博客 581

(转)ThreadPoolExecutor最佳实践--如何选择队列

转自:https://blog.hufeifei.cn/2018/08/12/Java/ThreadPoolExecutor%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5--%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9%E9%98%9F%E5%88%97/ 前一篇文章《如何选择线程数》讲了如何决定线程池中线程个数,这篇文章讨论“如何选择工作队列”。 再次强调一下,ThreadPoolExecutor最核心的四点: 1、当有任务提交的时候,...

PacosonSWJTU的博客 1468

【高效Python开发必备】:ThreadPoolExecutor线程池的8个最佳实践

掌握Python并发编程利器,提升任务执行效率。本文深入解析Python concurrent.futures.ThreadPoolExecutor在IO密集型任务中的应用,涵盖submit与map方法、线程复用、异常处理等8大实践要点,显著优化性能。高效开发必备,值得收藏。

Algorhythm的博客 886

【Java线程池核心参数深度解析】:掌握ThreadPoolExecutor的7大关键参数及最佳实践

掌握Java线程池核心原理,深入解析ThreadPoolExecutor的7大参数及其在高并发场景下的应用策略。涵盖核心线程数、队列选择、拒绝策略等关键配置方法,提升系统性能与资源利用率。java 线程池 threadpoolexecutor 参数详解,值得收藏

SimTrans的博客 1046

ThreadPoolExecutor最佳实践(基于负载的动态参数计算方法曝光)

掌握Java线程池ThreadPoolExecutor参数计算方法,基于实际负载动态调整核心参数。适用于高并发场景,通过CPU利用率、任务类型精准计算线程数与队列容量,提升系统性能与资源利用率,避免过度配置,值得收藏。

QuickCode的博客 1038

智能并发编程新体验:用快马AI一键生成ThreadPoolExecutor最佳实践

通过这次实践,我深刻体会到ThreadPoolExecutor在并发编程中的强大能力,以及像InsCode(快马)这样的AI编程平台给开发者带来的便利。核心线程数决定了线程池的基本规模,最大线程数限制了线程池的扩展上限,而队列容量则影响任务积压时的处理策略。这个Web爬虫系统需要具备几个核心功能:可配置的线程池参数、URL任务队列管理、网页下载和解析的并发执行、异常处理和重试机制,以及任务完成回调通知。在实现时,我特别注意了异常处理机制,包括网络请求失败的重试、解析错误的日志记录等。

MoonbeamRaven28的博客 932

Java 多线程实战:线程池的使用与最佳实践

线程池(ThreadPool)是一种多线程处理形式,处理过程中将任务添加到队列,然后在线程创建后自动启动这些任务。使用 ThreadPoolExecutor 替代 Executors合理配置核心线程数和最大线程数合理选择阻塞队列和拒绝策略。

2503_92674277的博客 332
上一篇: JDK 9~17 新特性及升级建议
下一篇: Spring Cloud LoadBalancer 最佳实践
fire-flyer
博客等级 码龄14年 218粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fire-flyer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值