getpoolsize()返回当前已创建且存活的线程总数,非正在执行数(getactivecount())、非核心数(getcorepoolsize())、非历史峰值(getlargestpoolsize())、非完成任务数(getcompletedtaskcount())。

getPoolSize() 方法返回的是线程池中当前**已创建、正在运行或处于空闲状态的线程总数**,它不包括已终止但尚未被回收的线程(比如刚执行完任务、还没被销毁的空闲线程),也不包括尚未创建的“预备线程”。这个值是线程池内部维护的实时计数,基本能反映“此刻有多少线程活着”。
它和哪些指标容易混淆?
很多人误以为 getPoolSize() 就是“正在干活的线程数”或“核心线程数”,其实不是:
- getActiveCount():才是当前**正在执行任务的线程数量**(即非空闲的线程数),通常 ≤ getPoolSize();
- getCorePoolSize():是线程池配置的**核心线程数下限**,是静态设定值,不会随运行变化;
- getLargestPoolSize():记录过的历史最大线程数(比如发生过扩容),是个峰值统计,只增不减;
- getCompletedTaskCount():已完成任务总数,和线程数量无关。
怎么验证 getPoolSize() 的真实性?
可以写个小例子观察变化:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, 5, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue(10)
);
System.out.println("初始: " + executor.getPoolSize()); // 输出 0(没任务时一般为 0)
executor.submit(() -> {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
});
System.out.println("提交1个任务后: " + executor.getPoolSize()); // 很可能输出 1 或 2(取决于是否触发核心线程创建)
executor.submit(() -> { Thread.sleep(1000); });
executor.submit(() -> { Thread.sleep(1000); });
System.out.println("提交3个任务后: " + executor.getPoolSize()); // 可能为 3(若核心数=2,第3个可能触发扩容)
注意:如果队列未满且线程数 ≤ corePoolSize,新任务会优先复用空闲线程或创建新核心线程;只有当队列满、且线程数
使用时要注意什么?
- 该方法是线程安全的,可随时调用,但返回值是瞬时快照,多线程环境下可能刚读完就变了;
- 对于 ScheduledThreadPoolExecutor 或包装过的线程池(如 Spring 的 ThreadPoolTaskExecutor),需确认底层是否继承自 ThreadPoolExecutor,否则可能不支持或行为不同;
- 如果线程池已 shutdown() 或 terminated(),getPoolSize() 仍返回最后的有效值,不代表线程还在运行(实际可能正陆续终止);
- 想监控真实负载,建议结合 getActiveCount() 和 getQueue().size() 一起看。
替代方案:更全面的线程状态观察
单靠 getPoolSize() 不足以掌握全部情况。推荐组合查询:
- 活跃线程数:executor.getActiveCount()
- 排队中任务数:executor.getQueue().size()
- 已完成任务数:executor.getCompletedTaskCount()
- 是否已关闭:executor.isShutdown() / executor.isTerminated()
这些组合起来,才能较准确判断线程池当前是“忙不过来”、“空闲等待”,还是“正在优雅关闭”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











