线程池的拒绝策略是指,当线程池无法承载更多任务时执行的行为。也就是当线程池的核心线程数、最大线程、任务队列都满的情况下,又来了新的任务时,线程池执行的行为被称之为线程池的拒绝策略。
线程池的执行流程如下:
在 Java 中,线程池内置了以下四种拒绝策略(Rejected Execution Policy)。
示例代码:
new ThreadPoolExecutor(..., new ThreadPoolExecutor.AbortPolicy());
示例效果:
// 假设线程池已满,主线程提交任务时会直接执行该任务
executor.execute(task); // 主线程执行 task
示例代码:
new ThreadPoolExecutor(..., new ThreadPoolExecutor.DiscardPolicy());
示例代码:
new ThreadPoolExecutor(..., new ThreadPoolExecutor.DiscardOldestPolicy());
除了以上四种内置拒绝策略之外,程序中还可以通过实现 RejectedExecutionHandler 接口实现自定义策略:
public class CustomRejectionPolicy implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable task, ThreadPoolExecutor executor) {
// 自定义逻辑(如记录日志、持久化任务、重试等)
System.out.println("Task rejected: " + task);
// 保存任务信息
// 通知相关负责人
}
}
// 使用自定义策略
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue, new CustomRejectionPolicy()
);
策略 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
AbortPolicy | 默认拒绝策略,报错提示 | 需处理异常,增加代码复杂度 | 任务丢失不敏感的场景 |
CallerRunsPolicy | 任务一定执行 | 可能阻塞主线程,影响响应速度 | 非实时任务,允许延迟处理(如日志) |
DiscardPolicy | 简单高效,无额外开销 | 数据丢失风险高 | 可容忍数据丢失的场景(如监控采样) |
DiscardOldestPolicy | 优先处理新任务 | 可能丢失重要旧任务 | 时效性强的任务(如实时消息推送) |
CustomRejectionPolicy | 灵活 | 实现复杂 | 通常用于生产环境,先保存任务信息,再报警提示负责人 |