线程转储中JVM thread_state与java.lang.Thread.State的区别及实际状态确认
JVM thread_state 与 java.lang.Thread.State 的区别及实际状态判断
两者的核心区别
- java.lang.Thread.State:这是Java给应用开发者暴露的线程状态,基于Java线程模型定义,对应
java.lang.Thread类里的枚举值(比如RUNNABLE、BLOCKED、WAITING等),反映的是线程在Java代码执行层面的状态。 - JVM thread_state:这是JVM内部的线程状态,是JVM底层对线程运行状态的细节描述,包含了VM级别的锁、安全点、内部阻塞等信息,这类状态不会直接暴露给Java应用代码,属于JVM实现的内部逻辑。
示例中的状态分析
看你提供的这段线程转储:
“Test” #867 daemon prio = 5 os_prio = 0 tid = 0x820009600000 nid = 0x1260e7 [JVM thread_state = _thread_blocked, locked by VM(w / poll advisory bit) waiting on VM lock 'self_suspend_monitor for TID 1204455', polling bits:safep] java.lang.Thread .State : TIMED_WAITING(parking) at sun.misc.Unsafe.park(Native Method) - locked<0x000002000507d440>( a org.jctools.queues.MpscBlockingConsumerArrayQueue) at java.util.concurrent.locks.LockSupport .parkNanos(LockSupport.java : 215) at org.jctools.queues.MpscBlockingConsumerArrayQueue .parkUntilNext(MpscBlockingConsumerArrayQueue.java : 536) at org.jctools.queues.MpscBlockingConsumerArrayQueue .poll(MpscBlockingConsumerArrayQueue.java : 512) at datadog.trace.agent.common.writer .TraceProcessingWorker$TraceSerializingHandler .consumeFromPrimaryQueue(TraceProcessingWorker.java : 254) at datadog.trace.agent.common.writer .TraceProcessingWorker$DaemonTraceSerializingHandler .runDutyCycle(TraceProcessingWorker.java : 155) at datadog.trace.agent.common.writer .TraceProcessingWorker$DaemonTraceSerializingHandler .run(TraceProcessingWorker.java : 145) at java.lang.Thread.run(Thread.java : 807)
这里不存在“哪一个才是实际状态”的说法,两者是同一个线程在不同层面的状态描述:
- 从Java代码层面看,线程确实处于
TIMED_WAITING(parking)状态——它通过LockSupport.parkNanos方法在等待队列中的元素,这是应用层能感知到的状态。 - 从JVM底层层面看,线程同时处于
_thread_blocked状态,原因是它被VM内部的self_suspend_monitor锁阻塞,并且在等待JVM安全点(polling bits:safep),这是JVM内部运行时的细节状态。
简单说,这两个状态是互补的:线程原本在Java层面因park进入定时等待状态,同时又被JVM内部的锁机制阻塞,所以JVM层面标记为_thread_blocked。
内容的提问来源于stack exchange,提问作者vinay sharma
相关产品推荐
相关产品推荐

