掘地攀登
100.61M · 2026-03-29
在Java并发编程中,线程池是我们提升程序性能、管理系统资源的利器。它避免了频繁创建和销毁线程带来的开销。但要想用好线程池,深入理解其底层的配置参数和执行逻辑是必修课。今天,我们就来扒一扒线程池执行器的底裤,看看一个任务丢进线程池后,到底经历了什么。
要理解线程池的执行流程,首先得认识它的“七个武器”。在Java中,真正实现线程池的核心类是线程池执行器,它的全参构造函数包含了以下7个关键参数:
| 参数名 | 类型 | 核心作用 |
|---|---|---|
corePoolSize | int | 核心线程数。即使线程处于空闲状态,也不会被销毁(除非设置了允许核心线程超时)。 |
maximumPoolSize | int | 最大线程数。线程池允许创建的最大线程数量。 |
keepAliveTime | long | 空闲线程存活时间。当线程数大于核心线程数时,多余的空闲线程在这个时间内没活干就会被销毁。 |
unit | TimeUnit | 保持存活时间的时间单位(如秒、毫秒等)。 |
workQueue | BlockingQueue | 任务阻塞队列。用于存放被提交但尚未被执行的任务。 |
threadFactory | ThreadFactory | 线程工厂。用于定制线程的创建过程(如设置有意义的线程名称,方便排查问题)。 |
handler | RejectedExecutionHandler | 拒绝策略。当队列满了,且线程数达到最大限制时,对新任务的处理方式。 |
当一个新任务通过执行()或提交()方法提交到线程池时,它的命运将由上述参数共同决定。
整个调度流程可以总结为四个步骤、三道关卡:
第一关:核心线程(Core Pool) 当新任务提交时,线程池首先检查当前运行的线程数是否小于核心池大小。
第二关:任务队列(Work Queue) 如果核心线程池已满,线程池会尝试将任务塞进工作队列阻塞队列中。
第三关:最大线程数(Maximum Pool) 如果队列也被塞满了,此时线程池会检查当前运行的线程数是否小于最大泳池尺寸。
终局:拒绝策略(Rejected Policy) 如果线程数已经达到了最大泳池尺寸,且队列已满,线程池就会无情地触发处理程序拒绝策略。常见的策略有:
中止策略(默认):直接抛出异常,阻止系统正常运行。CallerRunsPolicy:把任务交给调用者所在的线程去执行。丢弃策略:默默丢弃任务,不抛出异常。丢弃最旧策略:丢弃队列中最老的任务,然后尝试重新提交新任务。为了方便开发者,Java的遗嘱执行人工具类提供了一些静态工厂方法,用于快速生成配置好的线程池。最常用的有以下三种:
固定线程池(固定大小线程池)核心池大小和最大泳池尺寸相等,全是核心线程,没有非核心线程。链接阻塞队列(无界队列,容量为整数.MAX_VALUE)。缓存线程池(缓存线程池)核心池大小为0,最大泳池尺寸为整数.MAX_VALUE(即2^31-1,相当于无限大)。非核心线程的空闲存活时间为60 秒。同步队列(同步队列,本身不存储元素,直接将任务交付给线程)。SingleThreadExecutor(单线程池)corePoolSize 和 maximumPoolSize 都是 1,池子里永远只有一个线程在工作。LinkedBlockingQueue(无界队列,即2^31-1)。避坑警告:为什么大厂禁止使用 Executors? 阿里巴巴《Java开发手册》中明确规定,不允许使用 Executors 去创建线程池,而是推荐通过 ThreadPoolExecutor 的方式。 原因在于 Executors 提供的方案存在严重的内存溢出(OOM)风险:
固定线程池和单线程执行器允许的请求队列长度为整数.MAX_VALUE,可能会堆积海量请求,导致OOM。缓存线程池允许创建的线程数量为整数.MAX_VALUE,可能会创建极多的线程,同样导致OOM。最佳实践:老老实实使用线程池执行器构造函数,根据业务场景自己评估并设定合理的队列长度和最大线程数!
女神漫画官方客户端下载安装最新版本怎么进 - 女神漫画免费下载地址安卓苹果
28-模块四-AI代码审核实战 第28讲-代码质量评分体系 - 可维护性 可读性 可测试性的量化指标
2026-03-29
2026-03-29