线程池队列满了会怎样?从拒绝策略看懂 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 文档把这件事说得很明确:有限的最大线程数和有限队列同时耗尽时,任务才会被拒绝。面试里把这条路径讲清,再结合你的业务说为什么选有界队列和哪一种拒绝策略,已经比背参数表强很多。

相关推荐
晓晓_za89866832 分钟前
多租户 GEO 优化系统源码架构:权限隔离与数据分离实现
java·tcp/ip·spring·缓存·微服务·架构
AI行业应用研究33 分钟前
2026年主流报名工具测评报告:眨眼猫会务智能体报名小程序为何成为多场景首选?
java·开发语言·小程序
cxoptics35 分钟前
C-Lens在光模块(800G/1.6T)中的应用
java
liangbo738 分钟前
JVM规范第 1章:从一段历史到「JVM 并不认识 Java」
java·jvm
TechExplorer3651 小时前
Tomcat 下载与安装
java·tomcat
程序员贺加贝1 小时前
列表导出不够用-SaaS-ERP-单据详情导出的-Provider-模板与文档型-Excel-设计
java·后端·设计模式·架构·excel
SimonKing1 小时前
写文档的最佳搭档:Typora+PicList+SM.MS
java·后端·程序员
侧耳倾听1111 小时前
disruptor 从入门到使用
java
龙智DevSecOps解决方案1 小时前
WildFly vs JBoss vs GlassFish:2026年Java应用服务器选型对比与Perforce JRebel加速实践
java·应用服务器·jrebel·wildfly