Skip to content
基础

一句话答案

四种策略:AbortPolicy(抛异常)、CallerRunsPolicy(调用者执行,推荐)、DiscardPolicy(丢弃)、DiscardOldestPolicy(丢最老)。

核心要点

四种策略:

策略行为适用场景
AbortPolicy(默认)抛 RejectedExecutionException关键任务,不允许丢失
CallerRunsPolicy由提交任务的线程执行降速不丢任务(背压机制)
DiscardPolicy静默丢弃新任务允许丢失的非关键任务
DiscardOldestPolicy丢弃队列最老的任务只关心最新任务

生产建议:

  • 不要用默认的 AbortPolicy(异常容易被吞)
  • 推荐 CallerRunsPolicy:自动限流,不会丢任务
  • 自定义策略:记录日志 + 持久化到 MQ/DB + 告警
java
new ThreadPoolExecutor.CallerRunsPolicy()
// 或自定义:
(r, executor) -> {
    log.warn("Task rejected: {}", r);
    // 持久化到MQ重试
}
追问与易错

追问方向:

  • CallerRunsPolicy 有什么问题?
  • 你会怎么自定义拒绝策略?
  • 线程池不当导致过什么线上问题?

易错点:

  • ❌ 默认 AbortPolicy 就好——异常容易被吞
  • ❌ 拒绝策略不重要——是系统保护最后一道防线

💡 记忆锚点

线程池满了像餐厅客满:Abort 是直接在门口报警赶客(抛异常),CallerRuns 是让老板亲自端盘子(调用者线程干活,自动限流),Discard 是悄悄把新客人赶走(静默丢弃),DiscardOldest 是把等最久的人请走腾位置。生产上推荐 CallerRuns 或自定义(记日志+存 MQ 重试)。