线程池 RejectedExecutionException 异常:Task ... rejected from...
问题与处理策略
问题描述
- 在使用线程池时,遇到 java.util.concurrent.RejectedExecutionException 异常
java.util.concurrent.RejectedExecutionException:
Task ... rejected from java.util.concurrent.ThreadPoolExecutor@149a36f[Running, pool size = 7, active threads = 7, queued tasks = 10, completed tasks = 1846]
问题原因
- RejectedExecutionException 异常,这个错误表明线程池已经达到了其处理能力的上限,无法接受新的任务,线程池状态如下
-
pool size = 7
:当前线程池中的线程数 -
active threads = 7
:所有线程都在忙碌 -
queued tasks = 10
:等待执行的任务数 -
completed tasks = 1846
:已经完成的任务数
- 线程池已达到最大线程数(7 个),且队列已满(已经有 10 个任务在等待),线程池使用了默认的 AbortPolicy 拒绝策略,可能有如下原因
-
核心线程数和最大线程数可能设置过小
-
任务队列容量可能不足
-
任务执行时间可能过长
-
任务产生速度可能过快
处理策略
- 调整线程池配置,调整核心线程数、最大线程数、空闲线程存活时间、使用更大的队列、改变拒绝策略等
ExecutorService executor = new ThreadPoolExecutor(4, // 核心线程数6, // 最大线程数60, // 空闲线程存活时间TimeUnit.SECONDS, // 空闲线程存活时间单位new ArrayBlockingQueue<>(100), // 使用更大的队列Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy() // 改变拒绝策略,例如,使用 CallerRunsPolicy,当队列满时由提交任务的线程执行
);
- 或者,捕获并处理 RejectedExecutionException 异常
try {pool.execute(() -> {...});
} catch (RejectedExecutionException ex) {handleRejectedExecutionException(ex);
}