# 39. 线程池拒绝策略分析
# 标准答案
✅ 线程池拒绝策略的选择和设计:
JDK内置拒绝策略:
- AbortPolicy:直接抛出异常(默认策略)
- CallerRunsPolicy:由调用线程执行任务
- DiscardPolicy:直接丢弃任务
- DiscardOldestPolicy:丢弃队列最旧任务
自定义拒绝策略场景:
- 任务降级处理
- 任务延迟处理
- 任务优先级处理
- 任务日志记录
- 任务监控告警
最佳实践建议:
- 核心系统使用CallerRunsPolicy实现优雅降级
- 非核心系统可以使用DiscardPolicy
- 监控系统必须使用自定义策略记录信息
# 答案解析
# 1️⃣ 内置拒绝策略详解
// AbortPolicy:抛出异常
new ThreadPoolExecutor.AbortPolicy();
// CallerRunsPolicy:调用者执行
new ThreadPoolExecutor.CallerRunsPolicy();
// DiscardPolicy:直接丢弃
new ThreadPoolExecutor.DiscardPolicy();
// DiscardOldestPolicy:丢弃最旧任务
new ThreadPoolExecutor.DiscardOldestPolicy();
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 2️⃣ 自定义拒绝策略实现
public class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// 1. 记录日志
log.warn("Task rejected: {}", r);
// 2. 发送监控告警
AlertUtil.sendAlert("线程池任务拒绝");
// 3. 任务降级处理
if (r instanceof PriorityTask) {
handlePriorityTask((PriorityTask) r);
} else {
// 普通任务直接丢弃
log.info("Discard task: {}", r);
}
}
private void handlePriorityTask(PriorityTask task) {
// 优先级任务降级处理
if (task.getPriority() > 5) {
// 高优先级任务,尝试延迟处理
delayQueue.offer(task);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 常见误区
- ❌ 误区1:认为拒绝策略不重要
- ❌ 误区2:一直使用默认的AbortPolicy
# 典型场景与解决方案
# ✅ 订单处理系统的拒绝策略
public class OrderRejectedHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if (r instanceof OrderTask) {
OrderTask task = (OrderTask) r;
// 1. 记录监控指标
MetricsUtil.recordRejection("order_task");
// 2. 存入延迟队列
DelayQueue<OrderTask> delayQueue = DelayQueueHolder.getQueue();
delayQueue.offer(task);
// 3. 发送告警
if (task.getOrderAmount() > 10000) {
AlertUtil.sendHighPriorityAlert("高金额订单处理延迟");
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 企业实战经验
# Situation(业务背景)
支付系统在双11期间遇到流量峰值,线程池出现任务拒绝。
# Task(核心任务)
设计合理的拒绝策略,确保支付业务的稳定性。
# Action(解决方案)
- 实现自定义拒绝策略
- 对接实时监控系统
- 实现任务优先级处理
- 设置任务重试机制
# Result(结果)
- 系统可用性提升到99.99%
- 重要交易零丢失
- 监控覆盖率100%
# 深入追问
🔹 如何选择合适的拒绝策略?
- 考虑业务重要性
- 评估系统容量
- 分析任务特性
🔹 如何处理被拒绝的任务?
- 实现降级逻辑
- 使用延迟队列
- 记录监控数据
# 相关面试题
- 线程池的拒绝策略有哪些?
- 如何实现自定义拒绝策略?
- 不同场景下如何选择拒绝策略?