目录
在介绍线程池的核心配置参数和流程前,我们先简单了解什么是线程池~~
1. 什么是线程池
线程池是一种缓存线程的机制,就像一个 “线程工厂”,预先创建一定数量的线程,将它们放到一个池子(容器)里。当有任务需要执行时,直接从线程池里获取一个空闲线程来处理任务;任务处理完成后,线程不会被销毁,而是归还给线程池,等待执行下一个任务。
简单来说:线程池是用于对线程的管理和重复利用的机制,避免线程频繁的创建和销毁会带来额外的开销
-
线程池的核心类与接口
-
接口
Executor接口:顶层接口,定义了任务提交方法execute(Runnable command)
ExecutorService:基于Executor接口,扩展了线程池管理的方法。例如shutdown()、 submit()、awaitTermination()
-
实现类
ThreadPoolExecutor:借助 Worker 工作线程、`BlockingQueue` 阻塞队列和拒绝策略,实现标准线程池 。
ScheduledThreadPoolExecutor:作为 `ThreadPoolExecutor` 子类,用 `DelayedWorkQueue`(按任务执行时间排序的优先队列 ),支持按时间周期执行任务,适合作业调度场景 。
ForkJoinPool:基于分治思想,通过 “分叉(`fork`) - 合并(`join`)” 拆分大任务为小任务,为线程配工作队列减少竞争,适合计算密集型场景,补充 `ThreadPoolExecutor 。
其中ThreadPoolExecutor是我们最常用的线程池
在创建线程池时,我们不可避免地与一些核心配置参数打交道,这些参数直接决定了线程池地运行特性和性能表现,如下:
//创建线程池
ExecutorService executor=new ThreadPoolExecutor(
10, //corePoolSize
100, //maximumPoolSize
60, //keepAliveTime
TimeUnit.SECONDS, //TimeUnit
new LinkedBlockingQueue<>(), //BlockingQueue
new MyFactory("肥嘟嘟"), //ThreadFactory
new ThreadPoolExecutor.AbortPolicy() //RejectedExecutionHandler
);
那这些参数有什么样的意义 ,又是如何决定了线程池地运行特性和性能表现的呢
2. ThreadPoolExecutor核心配置参数
【corePoolSize】线程池核心线程数:也可以理解为线程池维护的最小线程数量,核心线程创建后不会被回收。大于核心线程数的线程,在空闲时间超过 keepAliveTime 后会被回收; 【maximumPoolSize】线程池最大线程数:线程池允许创建的最大线程数量;(包含核心线程池数量)
【keepAliveTime】非核心线程线程存活时间:当一个可被回收的线程的空闲时间大于 keepAliveTime ,就会被回收。
- 当线程池中的线程数大于 corePoolSize 时,如果一个线程空闲的时间达到 keepAliveTime ,则会被回收,直到线程池中的线程数不超过 corePoolSize 。
- 如果设置 allowCoreThreadTimeOut = true ,在线程池中的线程数不大于 corePoolSize 时,keepAliveTime 参数也会起作用,直到线程池中的线程数为 0;
【TimeUnit】时间单位:参数 keepAliveTime 的时间单位;
【BlockingQueue】阻塞工作队列:用来存储等待执行的任务;
【ThreadFactory】线程工厂:用于创建线程,以及自定义线程名称,需要实现 ThreadFactory 接口;
【RejectedExecutionHandler】拒绝策略:当线程池线程内的线程耗尽,并且工作队列达到已满时,新提交的任务,将使用拒绝策略进行处理;
这些核心配置参数 通过控制线程池 “何时创建线程、何时回收线程、任务怎么排队、无法处理任务时如何兜底” 的执行流程,从根本上决定了线程池的运行特性(比如是否灵敏响应任务、是否节省资源)和性能表现(处理任务的吞吐量、延迟),接下来我们详细说明线程池到底是怎么执行的~
3.线程池的执行流程
1. 提交一个新线程任务,线程池会在线程池中分配一个空闲线程,用于执行线程任务;
2. 如果线程池中不存在空闲线程,则线程池会判断当前“存活的线程数”是否小于核心线程数 corePoolSize 。
- 如果小于核心线程数 corePoolSize ,线程池会创建一个新线程(核心线程)去处理新线程任务;
- 如果大于核心线程数 corePoolSize ,线程池会检查工作队列;
- 如果工作队列未满,则将该线程任务放入工作队列进行等待。线程池中如果出现空闲线 程,将从工作队列中按照FIFO的规则取出1个线程任务并分配执行;
- 如果工作队列已满,则判断线程数是否达到最大线程数 maximumPoolSize ;
- 如果当前“存活线程数”没有达到最大线程数 maximumPoolSize ,则创建一个新线程(非核心线程)执行新线程任务;
- 如果当前“存活线程数”已经达到最大线程数 maximumPoolSize ,直接采用拒绝策略处理新线程任务;
综上所述,执行顺序为:核心线程、工作队列、非核心线程、拒绝策略。
线程池流程图
4.总结
线程池通过 “预创建线程 + 动态伸缩 + 队列调度 + 拒绝兜底” 的机制,解决了线程频繁创建销毁的性能损耗问题,同时用 corePoolSize
maximumPoolSize
等参数,精准控制线程资源的弹性伸缩。从任务提交到拒绝策略的完整流程,让线程池既能高效响应突发任务(靠核心线程快速执行、非核心线程应急扩容),又能通过队列和拒绝策略保障系统稳定性(避免任务无限制堆积拖垮内存)。本质是用一套可配置的 “线程资源管家” 逻辑,平衡了性能、资源、稳定性三者的矛盾,成为高并发场景下任务调度的基础支撑。
本猪是萌新,有不完善或者不正确的地方,欢迎大家留言。🐽
肥嘟嘟左卫门就讲到这里啦,麻烦大家一键三连!!!🐽