You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ThreadPoolExecutor活跃线程为0时抛出RejectedExecutionException的原因排查

问题

我使用ThreadPoolExecutor创建了如下线程池:

executor = new ThreadPoolExecutor(4, 10, 10000000, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(1));

并通过如下代码读取GZIP文件提交任务:

try { 
    GZIPInputStream gzipIS = new GZIPInputStream(new FileInputStream("filePath")); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(gzipIS, Charset.forName("UTF-8"))); 
    String line = null; 
    while ((line = reader.readLine()) != null) { 
        executor.execute(new ParallelScan(line)); 
    } 
} catch (Exception e) { 
    System.out.printf("Exception == " + e); 
}

线程池最大线程数设为10,但在活跃线程数为0时仍抛出异常:

java.util.concurrent.RejectedExecutionException: java.util.concurrent.ThreadPoolExecutor@33990a0c[Running, pool size = 10, active threads = 0, queued tasks = 0, completed tasks = 23]

已知execute抛出该异常的两种常见原因:1.队列已满无法添加任务;2.线程池已关闭,但这两种情况均不适用,请问异常原因是什么?

分析与解答

这个异常的核心原因是线程池的饱和策略触发逻辑,结合配置参数拆解如下:

  • 你的线程池参数:核心线程数4,最大线程数10,队列是容量仅为1的ArrayBlockingQueue。
  • 线程池处理任务的优先级逻辑:先创建核心线程(最多4个)→ 核心线程满后任务入队(最多1个)→ 队列满后创建非核心线程(最多到10个)→ 线程数达最大且队列满时触发饱和拒绝。

异常信息显示的pool size=10, active threads=0是异常抛出后的线程池状态,而非触发拒绝的瞬间状态:
当任务提交速度远快于线程处理速度时,会短暂出现“线程数已达10、队列已满”的临界状态,此时提交新任务直接触发拒绝策略;等异常信息输出时,之前的任务已经处理完成,线程回到空闲状态,就出现了活跃线程为0的情况。

另外你设置的空闲线程存活时间长达10000000分钟,空闲线程几乎不会被回收,线程数到达10后会一直维持这个规模,后续只要任务提交速度超过处理速度导致队列满,就会触发拒绝,哪怕之后线程又空闲下来。

内容的提问来源于stack exchange,提问作者Mounika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 03:36:28