Java线程池四种内置拒绝策略:AbortPolicy抛异常适用于可重试的关键任务;CallerRunsPolicy由提交线程执行任务,适合需限流的后台作业;DiscardPolicy静默丢弃,仅用于无影响的采样类任务;DiscardOldestPolicy丢弃队列头任务再重试,可能破坏公平性。

Java 线程池的拒绝策略有四种内置实现,它们在任务无法被接纳时(即:线程数已达 maximumPoolSize 且工作队列已满)触发,作用是决定如何处理“进不来的任务”。选对策略,关键看三点:任务是否允许丢失、调用方能否承担额外开销、系统是否需要自我调节能力。
AbortPolicy:默认“抛异常”,适合关键路径
行为是直接抛出 RejectedExecutionException。它不掩盖问题,让调用方立刻感知过载。
- 适用场景:任务不能丢,且上层能捕获异常做降级、重试或告警,比如核心业务回源、支付回调处理
- 注意点:必须显式 try-catch,否则异常会中断流程;高频拒绝时构造异常栈有轻微性能开销
- 配置方式:
new ThreadPoolExecutor.AbortPolicy()(不指定 handler 时自动启用)
CallerRunsPolicy:让提交者自己跑,天然背压
被拒任务由提交线程(如 Tomcat 的请求线程、调度线程)直接执行。相当于把压力“推回上游”,降低后续提交速率。
- 适用场景:任务不可丢,又希望系统自动限流,比如批量补齐、推送通知等后台任务
- 风险点:若提交线程是 HTTP 请求线程,执行任务会拖慢响应;需确保该线程有能力安全执行任务逻辑
- 优势:避免异常开销,不丢任务,还自带节流效果
DiscardPolicy:静默丢弃,适合非关键任务
什么也不做,直接扔掉新任务,不抛异常、不执行、不通知。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 适用场景:任务可丢失、可重来或仅用于优化,比如埋点上报、缓存预热、日志异步刷盘
- 隐患:完全无感丢弃,极易漏监控——必须搭配外部指标(如拒绝计数+告警)才能及时发现
- 优点:轻量、零干扰,不影响线程池和调用方正常运行
DiscardOldestPolicy:丢最老的,保最新的
先从工作队列头部移除一个等待最久的任务,再尝试把当前任务加入队列。
- 适用场景:数据时效性远大于完整性,比如实时行情刷新、状态心跳、消息轮询
- 特点:仍属静默丢弃(丢的是旧任务),同样依赖监控兜底;不适合依赖顺序或强一致性的任务
- 注意:如果队列是 SynchronousQueue(容量为 0),此策略退化为直接丢弃
不复杂但容易忽略:拒绝策略不是孤立配置的,它和 workQueue 类型(有界/无界)、core/max 线程数比例、任务提交频率 共同决定系统表现。例如,用无界队列(如 LinkedBlockingQueue 无容量限制)会让 Discard 系列策略几乎永不触发,反而可能引发 OOM;而用有界队列 + CallerRunsPolicy 是很多高可用后台服务的稳健组合。

















