线程池拒绝策略详解及选择建议
请说明ThreadPoolExecutor的4种拒绝策略的行为和适用场景。
回答
我是大山
1. AbortPolicy(默认)
- 行为:抛出RejectedExecutionException异常。
- 场景:不能丢失任务,且需要立即感知线程池过载的场景。
- 注意:调用方需捕获异常处理。
2. CallerRunsPolicy
- 行为:由调用线程(提交任务的线程)直接执行该任务。
- 场景:降级处理,放慢任务提交速度(提交者执行任务,阻塞提交)。
- 优点:不需要额外处理,提交者被阻塞后自然减少了提交频率。
- 阿里规推荐:数据库写入场景,防止大量任务堆积。
3. DiscardPolicy
- 行为:直接丢弃被拒绝的任务(不抛异常)。
- 场景:不重要的任务,如日志记录、统计信息。
- 风险:静默丢失任务,需谨慎使用。
4. DiscardOldestPolicy
- 行为:丢弃队列中最老的任务(队首),然后重新提交当前任务。
- 场景:优先级最新的任务更重要,如实时消息推送。
- 注意:不能和PriorityBlockingQueue混用。
自定义策略:实现RejectedExecutionHandler接口。 阿里Java规约推荐CallerRunsPolicy作为兜底策略。