• ThreadPoolExecutor 基础入门


    本文基于版本为 1.8.0_281 的 JDK 对 ThreadPoolExecutor 的源码进行分析
    在这里插入图片描述
    不知道比较新的 JDK 内 ThreadPoolExecutor 内实现咋样的,应该大差不差吧,研究好主流的 JDK 1.8 一通百通。

    全局概览

    先来说下使用线程池的好处:

    1. 核心线程可以复用,省去创建线程的开销
    2. 通过合理的参数控制线程的数量,可以防止服务器资源消耗过多
    3. 提供了大量统计相关的方法,方便对线程池进行管理

    再来说下大概的流程:

    1. 线程总数量 < corePoolSize,总会创建一个新的核心线程执行任务
    2. 线程总数量 >= corePoolSize 时,新来的线程任务进入任务队列中等待,然后空闲的核心线程去队列中取任务执行
    3. 当队列满了后,再来新的任务时启动非核心线程去执行任务
    4. 队列也满了,总线程数达到 maximumPoolSize,采取聚集策略进行处理

    ThreadPoolExecutor 源码分析

    构造方法

    TODO

    使用

    自定义线程池

    先来说下为什么要自定义线程池?

    一种情况是自带那几种线程池的有问题,具体有哪些问题呢?下面我们一个一个来说:

    1. CachedThreadPool:创建了一个「最大线程数为 Integer.MAX_VULUE 」的线程池,如果线程任务耗时并且大量创建,会导致 OOM;
    2. FixedThreadPool:创建了一个固定大小可重复的线程池,队列是 LinkedBlockingQueue 无界阻塞队列(因为其默认大小是 Integer.MAX_VALUE),随着任务越来越多,队列中的任务也越来越多,可能会导致 OOM;
    3. SingleThreadExecutor:创建了一个只有一个线程的线程池,队列是 LinkedBlockingQueue 无界阻塞队列(因为其默认大小是 Integer.MAX_VALUE),随着任务越来越多,队列中的任务也越来越多,可能会耗尽 CPU 和内存资源;
    4. ScheduledThreadPool:创建了一个能够定时执行任务或者在给定延迟后执行任务的线程池,队列用了 DelayQueue,也是个无界的,如果使用不恰当,也会 OOM。

    一种情况是给定的虽然在自己的业务场景下不会出问题,但是不满足我们的使用,需要我们进行自定义:

    1. 我们可以通过实现 RegectedExecutionHandler 接口来自定义策略;
    2. 对线程池中的线程设置更有标识作用的名字。

    结合 Spring

    TODO

    管理方法

    有了下述方法后,就可以直接使用相应的方法对线程池进行监控,当然也可以重新写一个自己的监控类 extends ThreadPoolExecutor,对某些方法的执行前后进行监控(比如启动、执行、关闭)。

    核心线程

    • getCorePoolSize():获取核心线程数
    • setCorePoolSize():重新设置线程池的核心线程数
    • prestartCoreThread():预启动一个核心线程,当且仅当工作线程数量小于核心线程数量
    • prestartAllCoreThreads():预启动所有核心线程

    线程池容量

    • getMaximumPoolSize():获取线程池容量
    • setMaximumPoolSize():重新设置线程池的最大容量

    线程存活

    • setKeepAliveTime():设置空闲工作线程的存活周期
    • getKeepAliveTime():获取空闲工作线程的存活周期

    线程队列

    • purge():移除任务队列中所有是Future类型并且已经处于Cancelled状态的任务
    • remove():从任务队列中移除指定的任务
    • BlockingQueue getQueue():获取任务队列的引用

    其他

    • getTaskCount():获取所有已经被执行的任务总数的近似值
    • getCompletedTaskCount():获取所有已经执行完成的任务总数的近似值
    • getLargestPoolSize():获取线程池的峰值线程数(最大池容量)
    • getActiveCount():获取所有活跃线程总数(正在执行任务的工作线程)的近似值
    • getPoolSize():获取工作线程集合的容量(当前线程池中的总工作线程数)

    关联阅读

    线程池运行源码分析

    ThreadPoolExecutor 关闭源码分析

    推荐阅读

    Java线程池实现原理及其在美团业务中的实践

  • 相关阅读:
    【软考 系统架构设计师】项目管理② 范围管理
    [文件共享] 电脑和设备通过网线共享文件夹
    C# 如何将表格数据转成实体
    rabbitmq安装部署和常用命令
    ​vmware虚拟机ubuntu系统配置静态ip​
    2025秋招NLP算法面试真题(四)- 解决老大难问题-如何一行代码带你随心所欲重新初始化bert的某些参数(附Pytorch代码)
    Go运算操作符全解与实战:编写更高效的代码!
    Nacos配置文件管理、微服务获取Nacos配置文件
    灵性图书馆:好书推荐-《在荷欧波诺波诺中遇见真正的自己》
    不再重蹈 Apache Log4j的覆辙,谷歌提出三项安全倡议
  • 原文地址:https://blog.csdn.net/MrBaymax/article/details/126006489