自定义 rejectedexecutionhandler 的核心是实现接口并注入 threadpoolexecutor 构造过程,仅在有界队列满且线程数达 maximumpoolsize 时触发;需避免递归调用 submit/execute,常见策略包括可观测、补偿和调用方感知型。

Java 中自定义 RejectedExecutionHandler 的核心,是实现接口并注入到 ThreadPoolExecutor 构造过程里——它不是补救手段,而是系统水位超限时的主动响应逻辑。
明确触发条件再动手
拒绝策略只在两个条件**同时成立**时才生效:
- 工作队列已满,且必须是有界队列(如
ArrayBlockingQueue(200));用LinkedBlockingQueue默认无界,任务会无限堆积,OOM 风险远高于触发拒绝 - 当前线程数已达
maximumPoolSize,包括核心与非核心线程
所以先确认你用的是有界队列,并设置合理容量(例如按峰值 QPS × 平均处理耗时 × 安全系数估算),否则自定义 Handler 永远不会被调用。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
实现 RejectedExecutionHandler 接口
只需重写 rejectedExecution(Runnable r, ThreadPoolExecutor executor) 方法:
-
r是被拒的任务,可能是普通Runnable或封装后的FutureTask -
executor可用来获取实时状态:getActiveCount()、getQueue().size()、getMaximumPoolSize()等 - 方法内可记录日志、发消息、落盘暂存,但不能调用
executor.submit()或execute(),否则可能递归触发拒绝甚至死锁
常见实用策略类型
根据业务目标选择主逻辑方向:
- 可观测型:记录关键上下文(任务类名、队列大小、活跃线程数),加日志限流(避免高频拒绝打爆磁盘或 I/O)
- 补偿型:异步发往 Kafka 或 RocketMQ 备份队列(带超时与降级,失败时 fallback 到本地文件暂存)
-
调用方感知型:抛出自定义异常(如
TaskRejectedException),由上游捕获后走降级流程,不静默吞任务
正确注册到线程池
必须在构建线程池时传入,后期无法替换:
- 使用
ThreadPoolExecutor构造器,第 8 个参数传入自定义实例 - 不要用
Executors.newFixedThreadPool()等工具类,它们内部固定使用AbortPolicy,无法更换 - 注意:只有
execute()和submit()会触发该策略;invokeAll()等批量方法也适用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










