🔧 线程池拒绝策略 自定义:程序员必知的实战技巧
大家好,我是常年混迹大厂面试间的程序员老王。今天聊聊线程池拒绝策略,尤其怎么玩转自定义策略——面试十有八九会问,实际项目也常踩坑!
📦 先领个福利(2025年Java面试宝典)
👉 链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g 提取码: 9b3g
覆盖大厂高频题,线程池、并发、JVM全有,看完面试横着走!
🧠 为什么需要线程池拒绝策略?
线程池不是“无限收容所”!当任务队列满、线程数达到maximumPoolSize,新任务咋办?
这时候线程池拒绝策略就登场了。默认策略虽能用,但灵活自定义才是高级玩家的选择。
🔄 四种默认拒绝策略(附坑点)
- AbortPolicy(甩手不干):直接抛
RejectedExecutionException→ 最常用但容易崩系统。 - CallerRunsPolicy(谁喊我谁干):任务退回给提交线程执行 → 可能拖慢调用方。
- DiscardPolicy(装没看见):默默丢弃新任务 → 数据丢了都不知道!
- DiscardOldestPolicy(踢走老人):丢弃队头任务 → 可能把重要任务扔了。

▲ 面试官超爱问:DiscardOldestPolicy 踢的是哪个任务?答案:队列里等最久的那位!
⚡ 为什么要自定义拒绝策略?
默认策略不够精细!比如:
- 日志报警:任务被拒了得留痕啊!
- 降级处理:调用备用服务 or 返回兜底数据
- 限流等待:让任务等几秒再重试
自定义的核心逻辑:实现RejectedExecutionHandler接口,重写rejectedExecution方法!
🔨 手撕一个自定义拒绝策略
直接上实战场景:任务被拒时,记录日志+尝试重试3次。
public class RetryRejectedHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable task, ThreadPoolExecutor executor) {
// 1. 打日志警告
log.warn("任务被拒绝! 尝试重试...");
// 2. 重试3次(模拟代码)
int retryCount = 0;
while (retryCount < 3 && !executor.isShutdown()) {
try {
if (executor.getQueue().offer(task, 1, TimeUnit.SECONDS)) {
return; // 塞进队列了!
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
retryCount++;
}
// 3. 彻底失败就记日志
log.error("任务 {} 被永久丢弃!", task);
}
}
💡 关键点面试这么答:
- 先判断线程池是否
isShutdown(),防止给关闭的池子塞任务 - 用
offer()非阻塞尝试入队,避免死等 - 重试次数别写死,做成可配置参数
🚀 实际应用场景
- 支付回调系统:任务被拒时,重试+触发短信告警
- 批量数据处理:丢弃旧任务的同时,记录被弃任务ID
- 高并发接口:触发拒绝策略后,直接返回“系统繁忙”提示

▲ 记住:自定义策略的核心是平衡“保系统”和“保业务”
❓ 面试灵魂拷问
-
什么时候触发拒绝策略?
答:队列满 + 线程数达到maxPoolSize(划重点:队列类型影响行为!) -
自定义策略要注意什么?
答:别阻塞提交线程!别忘判断线程池状态! -
用ThreadPoolExecutor构造方法怎么设置?
答:第7个参数就是放你的RejectedExecutionHandler实例!
🎁 隐藏福利时间
准备Java面试的兄弟注意了!在 面试鸭返利网 买会员找我返 25元(后台私我订单号就行)。省杯奶茶钱它不香吗?
注:会员题库含 20+大厂真题卷,尤其并发类题目有逐行源码解析👇
💎 总结
线程池拒绝策略不是摆设,自定义策略更是高并发系统的救命稻草。理解原理 + 实战编码 + 异常兜底,面试直接拿捏!
👉 下次碰到面试官问:“你的线程池任务被拒怎么办?” —— 把这篇甩他脸上!



