线程池队列满了会怎样?从拒绝策略看懂 ThreadPoolExecutor 的扩容顺序

线程池队列满了会怎样?

面试里问"线程池队列满了怎么办",别急着背四个拒绝策略。

拒绝不是队列一满就发生。对一个手动创建的 ThreadPoolExecutor,它会先尝试补到核心线程数;核心线程忙完后,才优先把任务放进队列;队列塞不下,才继续创建非核心线程;线程已经到最大值,才交给拒绝处理器。

这几个参数放在一起看,顺序就很直观:

java 复制代码
ThreadPoolExecutor pool = new ThreadPoolExecutor(
    2,
    4,
    30,
    TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(2),
    new ThreadPoolExecutor.AbortPolicy()
);

假设前几个任务都还没跑完。

  • 第 1、2 个任务:直接创建核心线程执行。
  • 第 3、4 个任务:核心线程已满,进入容量为 2 的队列。
  • 第 5、6 个任务:队列满了,继续创建线程,最多扩到 4 个。
  • 第 7 个任务:线程数和队列都到上限,才会触发 AbortPolicy,抛出 RejectedExecutionException

很多人答到这里会说"把队列调大就行"。这通常只是把超载藏起来。

无界队列会让 maximumPoolSize 基本失去作用:核心线程都忙时,后续任务一直排队,不会因为积压而扩到最大线程数。积压足够久,问题会从"被明确拒绝"变成"接口一直没返回,内存还在涨"。

有界队列不是为了制造拒绝,而是把延迟预算写进配置。比如单个任务平均 100 毫秒,4 个工作线程在稳定状态下每秒最多处理约 40 个任务。队列容量 200 意味着只看排队就可能多等约 5 秒。这个等待是否能接受,要由调用方的超时和业务时效决定。

四种默认拒绝策略,别按名字选

AbortPolicy 是默认值。它会抛异常,适合不能悄悄丢的任务。调用点要把它转换成可观测的过载信号,例如错误日志、指标和明确的失败响应。

CallerRunsPolicy 让提交任务的线程自己执行任务。它确实能给上游施加背压,但不要把它随手放进所有 Web 请求链路。调用线程如果是事件循环、持有锁,或者本身不能被长时间占用,背压会变成新的卡顿。

DiscardPolicy 会静默丢任务。除非业务天然允许丢弃,而且有丢弃计数和补偿手段,否则它最危险。日志里什么都没有,任务却已经没了。

DiscardOldestPolicy 会丢掉队列头部最早的任务,再重试提交当前任务。只在"新状态一定比旧状态更有价值"的场景才有讨论空间,例如可合并的最新状态刷新。对订单、通知、异步写库这类 FIFO 语义敏感的任务,不该用它赌运气。

生产里我更常把"拒绝"当成容量告警,而不是自动重试的起点。重试还是投回同一个已经饱和的池子,只会让队列更难退下来。

参数该从什么开始定?

先别从"CPU 核数乘几"起步,先把任务分开。

计算密集型任务,线程太多会把时间花在线程切换上;阻塞型任务可以容纳更多并发,但它占住的往往是数据库连接、下游 HTTP 配额或文件句柄。线程池最大值必须同时受这些下游资源约束。

然后拿高峰提交速率、单任务耗时、可接受排队时长推一个初始容量,再压测。观察至少三组数:活跃线程数、队列长度、拒绝次数。只有队列长度,没有拒绝次数,往往看不出"已经开始掉任务"还是"只是慢了一点"。

JDK 的 ThreadPoolExecutor 文档把这件事说得很明确:有限的最大线程数和有限队列同时耗尽时,任务才会被拒绝。面试里把这条路径讲清,再结合你的业务说为什么选有界队列和哪一种拒绝策略,已经比背参数表强很多。

相关推荐
Flynt12 分钟前
Java 27 升级实测:默认值动得比新特性多,有个老参数会让 JVM 直接起不来
java·jvm·后端
Bs_MoneyMagnet14 分钟前
基于springboot+vue的个人健康管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·vue3·springboot3·计算机毕业设计
星云API技术支持35 分钟前
企业微信二次开发:群权限设置、成员管理与群资料维护的接口组合实践
java·前端·企业微信
niucloud-admin1 小时前
JAVA V6 多商户商城 开发文档——job 计划任务开发
java·python·github
海宇AI2 小时前
零信任架构实战:基于海宇柠檬查出险-登记证构建自动化车抵贷核保网关
java·人工智能·架构·自动化
cfm_29143 小时前
单例模式详解
java
我叫张土豆4 小时前
本体论、DDD、SDD、TDD:AI 编程时代的四层认知栈
java·人工智能
白远山4 小时前
家政服务家政社区派单实战:调度系统架构设计与实现指南
java·开发语言·小程序·架构·需求分析
海南java第二人4 小时前
从诞生到回收:JVM对象生命周期与垃圾回收全链路解析
java
SL_staff4 小时前
JVS-Logic:从页面配置工具到企业级业务逻辑中枢的技术演进
java·算法·全栈