thread.activecount()返回当前线程组中活跃线程的近似数,包含jvm初始线程(如main、reference handler等)及已start未终止的用户线程,不统计线程池等独立线程组中的线程。

Thread.activeCount() 返回的是当前线程所属线程组中活跃线程的近似数量,不是整个 JVM 的精确线程总数,也不是你“主观认为创建了多少个线程”的数字。它的值受线程组范围、线程生命周期、守护线程状态以及是否已启动等因素影响。不同创建和运行模式下,它的“基数”(即初始参考值)会明显不同。
默认主线程组里的基础线程数
JVM 启动时,即使你没写任何 new Thread(),也会自带若干系统线程:
-
main线程(你的程序入口) -
Reference Handler(处理软/弱引用) -
Finalizer(执行对象 finalize 方法,JDK 9+ 已废弃但部分环境仍存在) -
Signal Dispatcher(处理 JVM 信号) -
Attach Listener(支持 jcmd、jstack 等工具动态 attach)
这些线程多数是 守护线程(daemon),但 activeCount() 统计所有状态为 RUNNABLE、BLOCKED、WAITING、TIMED_WAITING 的线程,包括守护线程——只要它们还没终止。
所以,刚进入 main 方法时调用 Thread.activeCount(),常见返回值是 3~6,具体取决于 JDK 版本和 JVM 参数(如 -XX:+UseParallelGC 可能额外启用 GC 线程)。
继承 Thread 类方式下的 activeCount 变化
class MyThread extends Thread {
public void run() { /* ... */ }
}
new MyThread().start(); // 启动后才计入 activeCount
- 仅
new MyThread()不会增加计数; - 必须调用
start(),线程进入RUNNABLE或TIMED_WAITING等活跃状态才算; - 每个
start()成功后,activeCount()通常 +1(前提是线程尚未结束); - 若线程极快执行完(比如空 run 方法),可能在你调用
activeCount()前已进入TERMINATED,不被统计。
⚠️ 注意:多个 MyThread 实例共享同一个线程组(默认是 main 线程组),所以都计入 activeCount()。
实现 Runnable 接口方式下的基数表现
Thread t = new Thread(() -> { /* task */ });
t.start();
- 行为与继承
Thread完全一致:只有start()后才被计入; -
activeCount()不关心你是怎么创建线程对象的,只看线程是否处于活跃状态; - 同一线程组内,
Runnable方式创建的线程和Thread子类创建的线程无区别。
✅ 优势在于解耦,但对 activeCount() 数值无影响。
线程池场景下的 activeCount 值特点
使用 Executors.newFixedThreadPool(3):
- 线程池内部线程是复用的,且属于自定义线程组(非
main组); -
Thread.activeCount()只统计调用方所在线程组的线程,即默认仍是main线程组; - 所以即使线程池里有 3 个正在跑任务的工作线程,
activeCount()通常不包含它们(除非你显式把线程池线程加入main组,一般不会); - 若想获取线程池活跃线程数,应调用
ThreadPoolExecutor.getActiveCount(),而非Thread.activeCount()。
类似地:
-
Executors.newCachedThreadPool()创建的线程默认也归属独立线程组; -
ForkJoinPool.commonPool()的线程也不计入activeCount()。
Callable + FutureTask 方式不影响 activeCount 基数逻辑
FutureTask<string> ft = new FutureTask(() -> "done"); new Thread(ft).start();</string>
- 本质仍是
new Thread(...).start(),只是任务带返回值; - 启动后该线程计入
activeCount(); -
ft.get()是阻塞调用,但不会新增线程,不影响计数。
简单说:activeCount() 的“基数”由 JVM 初始线程 + 当前线程组中所有已 start 且未 TERMINATED 的线程共同决定;它不区分创建方式,只认线程状态和所属线程组。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











