java线程池自定义拒绝策略需实现rejectedexecutionhandler并抛出自定义taskrejectedexception异常,而非使用默认abortpolicy;构造threadpoolexecutor时传入该处理器,调用execute()或submit()时触发,调用方须显式捕获该异常进行降级处理。

Java线程池默认的拒绝策略(如 AbortPolicy)在任务被拒绝时会直接抛出 RejectedExecutionException,但这个异常是 JDK 自带的、不可变的。若想抛出自定义异常(比如 TaskRejectedException),不能靠简单替换异常类型,而需自定义 RejectedExecutionHandler 实现,并在其中主动 throw 你自己的异常。
定义自己的 TaskRejectedException
先创建一个继承自 RuntimeException(或 Exception)的自定义异常类:
public class TaskRejectedException extends RuntimeException {
public TaskRejectedException(String message) {
super(message);
}
public TaskRejectedException(String message, Throwable cause) {
super(message, cause);
}
}
实现自定义 RejectedExecutionHandler
重写 rejectedExecution 方法,在其中抛出自定义异常,而不是调用父类逻辑:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 不要调用
super.rejectedExecution()(它最终仍会抛RejectedExecutionException) - 直接 throw 新的
TaskRejectedException,可携带任务、线程池等上下文信息 - 注意:该异常不会被线程池捕获处理,而是向调用
execute()或submit()的线程抛出
public class CustomRejectHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
String msg = String.format(
"Task %s rejected from %s, active=%d, queueSize=%d, poolSize=%d, maxPoolSize=%d",
r, executor, executor.getActiveCount(), executor.getQueue().size(),
executor.getPoolSize(), executor.getMaximumPoolSize()
);
throw new TaskRejectedException(msg);
}
}
将自定义拒绝策略应用到线程池
构造线程池时传入该 handler。注意:只有通过 execute() 提交任务才会触发拒绝策略;submit() 内部也调用 execute(),同样生效:
- 使用
ThreadPoolExecutor构造函数显式传入 handler -
Executors工具类创建的线程池不支持自定义 handler,必须手写构造 - 示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, 4, 60L, TimeUnit.SECONDS,
new LinkedBlockingQueue(10),
new CustomRejectHandler() // ← 关键
);
调用方需做好异常捕获
因为自定义异常是同步抛出的,调用 execute() 的代码必须 try-catch,否则会中断当前线程:
- 推荐在业务层捕获
TaskRejectedException,做降级、告警或重试 - 避免只 catch
RuntimeException,应精确捕获你的异常类型 - 示例:
try {
executor.execute(() -> doSomething());
} catch (TaskRejectedException e) {
log.warn("Task rejected, fallback triggered", e);
fallbackLogic();
}
不复杂但容易忽略的是:拒绝策略中的异常抛出是同步且不可绕过的,务必确保调用方有对应兜底逻辑。Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










