• 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线程池实现原理及其在美团业务中的实践

  • 相关阅读:
    数商云渠道商协同系统对机械企业的应用价值体现
    pytorch安装记录
    基于Flume+Kafka+Hbase+Flink+FineBI的实时综合案例(三)离线分析
    为何建议房企开发楼盘小程序?
    ABP - 依赖注入(1)
    【原创】Python 懂车帝口碑分爬虫
    07_03文件系统怎么玩的
    PHP基础学习第十九篇(了解MySQL数据库、MySQL的连接和创建数据库、MySQL创建数据表)
    轩辕:首个千亿级中文金融对话模型
    ArkTs快速入门
  • 原文地址:https://blog.csdn.net/MrBaymax/article/details/126006489