ThreadInfo 是 JVM 线程快照类,用于诊断死锁、阻塞等问题;含线程状态(如 RUNNABLE、BLOCKED)、堆栈轨迹及锁信息(持有/等待锁、显式锁列表),不可变且需通过 ThreadMXBean 安全获取。

ThreadInfo 是 Java 中用于获取线程快照信息的核心类,由 ThreadMXBean(Java 管理扩展 JMX 的一部分)在调用 dumpAllThreads 或 getThreadInfo 时返回。它不表示实时线程对象,而是某一时刻的“快照”,适用于诊断死锁、线程阻塞、CPU 占用异常等问题。
线程状态(Thread.State)
通过 threadInfo.getThreadState() 获取,返回标准的 java.lang.Thread.State 枚举值,如:
- RUNNABLE:正在运行或就绪,可能在执行 Java 代码,也可能在执行本地方法(如 I/O、synchronized 进入前的自旋)
- BLOCKED:等待进入 synchronized 块/方法,因锁被其他线程持有而挂起
-
WAITING / TIMED_WAITING:调用
Object.wait()、Thread.join()、LockSupport.park()等导致的主动等待 - TERMINATED:线程已结束执行
注意:Thread.State 是 JVM 抽象状态,不等同于操作系统线程状态(如 OS 的 “sleeping” 或 “running”),且无法反映 native 方法内部的阻塞细节。
堆栈跟踪(StackTraceElement[])
调用 threadInfo.getStackTrace() 返回当前线程执行路径的栈帧数组,从最新调用(栈顶)到最老调用(栈底)排列:
- 每项是
StackTraceElement,含类名、方法名、文件名、行号(若调试信息可用) - 对
WAITING/TIMED_WAITING线程,最后一帧通常是wait()、park()或join();对BLOCKED线程,通常停在synchronized关键字所在行 - 若栈为空(长度为 0),说明线程处于
NEW或TERMINATED状态,或栈被截断(如启用了-XX:+OmitStackTraceInFastThrow)
锁相关字段(锁持有与等待)
ThreadInfo 提供三类关键锁信息:
-
ownLockName / ownLockOwnerId:线程当前持有的锁标识(如
java.util.concurrent.locks.ReentrantLock$NonfairSync@12345678)及其持有者线程 ID(仅限可重入锁等显式锁) -
lockName / lockOwnerId:线程正在等待的锁标识及该锁当前持有者的线程 ID(适用于
BLOCKED或WAITING状态) -
lockedSynchronizers:线程已获取的所有显式锁(
java.util.concurrent.locks.Lock实例)列表,可用于分析锁粒度和嵌套持有情况
⚠️ 注意:synchronized 锁(内置锁)不会出现在 lockedSynchronizers 中,但会体现在 lockName 和线程状态中(如 BLOCKED 时的锁描述为 java.lang.Object@abcdef)。
如何安全获取 ThreadInfo
推荐使用 ManagementFactory.getThreadMXBean() 并设置参数控制开销:
- 启用堆栈:
getThreadInfo(tid, true)(第二个参数为boolean,决定是否采集栈) - 启用锁信息:
getThreadInfo(tid, true, true)(第三个参数为是否包含锁详情) - 批量获取时用
dumpAllThreads(false, false)可显著降低 GC 压力(不带堆栈和锁) - 避免在高频逻辑中调用;生产环境建议只在告警触发或人工 dump 时使用
不复杂但容易忽略:ThreadInfo 是不可变快照,多次调用 getThreadInfo 得到的结果可能不同——它反映的是每次调用瞬间的状态。

















