线程池问题

一、线程池拒绝策略选择指南

在实际开发中,线程池拒绝策略的选择需要根据具体的业务场景和系统需求来决定。Java线程池提供了四种内置拒绝策略,每种策略适用于不同的情况。

一、四种内置拒绝策略

  1. AbortPolicy(默认策略)
    行为:直接抛出RejectedExecutionException异常

适用场景:

需要明确知道任务被拒绝的情况

关键业务系统,不能容忍任务静默丢失

开发测试环境(便于发现问题)

示例:

java
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, 4, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2),
new ThreadPoolExecutor.AbortPolicy() // 显式指定
);
2. CallerRunsPolicy
行为:将任务回退给调用者线程执行

适用场景:

适合能承受一定延迟的业务

需要保证每个任务都能被执行

不希望任务丢失但可以接受降级

特点:

会降低新任务提交速度,起到负反馈调节作用

调用者线程可能被阻塞

  1. DiscardPolicy
    行为:静默丢弃被拒绝的任务,不做任何处理

适用场景:

非核心业务

允许丢失部分任务的场景

监控日志不重要的任务

风险:

任务丢失无感知,可能造成数据不一致

  1. DiscardOldestPolicy
    行为:丢弃队列中最老的任务,然后尝试重新提交当前任务

适用场景:

允许丢弃旧任务的新业务场景

实时性要求高的任务优先处理

任务本身具有时效性(旧任务价值低)

注意事项:

可能丢失重要但处理慢的任务

不适合任务之间有依赖关系的场景

二、选择策略的决策流程

  • 是否绝对不能丢失任务
    • 是:使用CallerRunsPolicy
    • 否:是否需要立即知道被拒绝
      • 是:使用AbortPolicy
      • 否:新任务比旧任务更重要
        • 是:使用DiscardOldestPolicy
        • 否:使用DiscardPolicy

三、实际业务场景推荐

  1. 支付/交易核心系统
    推荐策略:CallerRunsPolicy
    理由:保证每个支付请求都能被处理,宁可降级也不丢失

  2. 日志记录/数据收集
    推荐策略:DiscardPolicy
    理由:日志可容忍部分丢失,避免影响主业务流程

  3. 实时数据处理
    推荐策略:DiscardOldestPolicy
    理由:新数据比旧数据更有价值

  4. 管理系统后台任务
    推荐策略:AbortPolicy
    理由:需要及时发现系统过载情况

四、自定义拒绝策略
当内置策略不满足需求时,可以实现RejectedExecutionHandler接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class CustomRejectionPolicy implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// 1. 记录日志
log.warn("Task rejected: {}", r.toString());

// 2. 持久化任务到数据库/文件
persistTask(r);

// 3. 尝试重新提交
if (!executor.isShutdown()) {
executor.submit(r);
}
}
}

// 使用示例
executor.setRejectedExecutionHandler(new CustomRejectionPolicy());

五、配置建议
监控报警:无论选择哪种策略,都应监控拒绝情况

1
// 通过ThreadPoolExecutor的getRejectedExecutionCount()获取拒绝数

参数调优:合理设置队列容量和线程数比选择拒绝策略更重要

组合使用:不同业务使用不同线程池,配置不同策略

文档记录:在代码中明确注释选择该策略的原因

六、最佳实践总结
关键业务:优先保证任务执行(CallerRunsPolicy)

可丢弃任务:选择静默丢弃(DiscardPolicy)

需要感知:抛出异常(AbortPolicy)

时效敏感:丢弃旧任务(DiscardOldestPolicy)

特殊需求:自定义策略(如持久化后重试)

 wechat
天生我才必有用