import java.io.IOException;
public class JStackDemo1 {
public static void main(String[] args) {
while (true) {
//Do Nothing
}
}
}
$ jps
18464 Launcher
19600 Jps
5744
3896 Program
1148 JStackDemo1
输出如下信息
$ jstack 1148
2022-03-15 21:58:11
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.181-b13 mixed mode):
"Service Thread" #10 daemon prio=9 os_prio=0 tid=0x000000001a1d0800 nid=0x1764 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x0000000019b8f000 nid=0x980 waiting on condition [0x0000000000
000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x0000000019b3f000 nid=0x1f20 waiting on condition [0x000000000
0000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x0000000019ac3000 nid=0x3c94 waiting on condition [0x000000000
0000000]
java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x0000000019b26800 nid=0x41d8 runnable [0x0000000019ebe000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
- locked <0x00000000d6185420> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
- locked <0x00000000d6185420> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:47)
"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000019803800 nid=0x48f0 waiting on condition [0x000000000000
0000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000018476800 nid=0x4024 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x00000000038d9800 nid=0x1d8c in Object.wait() [0x00000000197be000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d5c08ed0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x00000000d5c08ed0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000000038d6000 nid=0x3d24 in Object.wait() [0x00000000196bf
000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d5c06bf8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000000d5c06bf8> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"main" #1 prio=5 os_prio=0 tid=0x00000000037e6800 nid=0x3d90 runnable [0x00000000035df000]
java.lang.Thread.State: RUNNABLE
at test.JStackDemo1.main(JStackDemo1.java:5)
"VM Thread" os_prio=2 tid=0x0000000018417800 nid=0x624 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000000037fc000 nid=0x250c runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00000000037fd800 nid=0x4c54 runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00000000037ff000 nid=0x446c runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000003800800 nid=0x4b08 runnable
"VM Periodic Task Thread" os_prio=2 tid=0x000000001a23b800 nid=0x41b0 waiting on condition
JNI global references: 12
重点关注以下的输出,用户线程的第五行
"main" #1 prio=5 os_prio=0 tid=0x00000000037e6800 nid=0x3d90 runnable [0x00000000035df000]
java.lang.Thread.State: RUNNABLE
at test.JStackDemo1.main(JStackDemo1.java:5)
以及下面的输出
"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000000038d6000 nid=0x3d24 in Object.wait() [0x00000000196bf
000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000d5c06bf8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x00000000d5c06bf8> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
线程锁住了0x00000000d5c06bf8,又等待0x00000000d5c06bf8,已经死锁了
补充一下线程的知识

Java语言定义了6种线程池状态:
New:创建后尚未启动的线程处于这种状态,不会出现在Dump中。
-RUNNABLE:包括Running和Ready。线程开启start()方法,会进入该状态,在虚拟机内执行的。
-Waiting:无限的等待另一个线程的特定操作。
-Timed Waiting:有时限的等待另一个线程的特定操作。
-阻塞(Blocked):在程序等待进入同步区域的时候,线程将进入这种状态,在等待监视器锁。
-结束(Terminated):已终止线程的线程状态,线程已经结束执行。
Dump文件的线程状态一般其实就以下3种:
-RUNNABLE,线程处于执行中
-BLOCKED,线程被阻塞
-WAITING,线程正在等待
Monitor 监视锁
因为Java程序一般都是多线程运行的,Java多线程跟监视锁环环相扣,所以我们分析线程状态时,也需要回顾一下Monitor监视锁知识。
有关于线程同步关键字Synchronized与监视锁的爱恨情仇,有兴趣的伙伴可以看一下我这篇文章 Synchronized解析——如果你愿意一层一层剥开我的心
Monitor的工作原理图如下:

线程想要获取monitor,首先会进入Entry Set队列,它是Waiting Thread,线程状态是Waiting for monitor entry。
当某个线程成功获取对象的monitor后,进入Owner区域,它就是Active Thread。
如果线程调用了wait()方法,则会进入Wait Set队列,它会释放monitor锁,它也是Waiting Thread,线程状态in Object.wait()
如果其他线程调用 notify() / notifyAll() ,会唤醒Wait Set中的某个线程,该线程再次尝试获取monitor锁,成功即进入Owner区域。
Dump 文件分析关注重点
- runnable,线程处于执行中
- deadlock,死锁(重点关注)
- blocked,线程被阻塞 (重点关注)
- Parked,停止
- locked,对象加锁
- waiting,线程正在等待
- waiting to lock 等待上锁
- Object.wait(),对象等待中
- waiting for monitor entry 等待获取监视器(重点关注)
- Waiting on condition,等待资源(重点关注),最常见的情况是线程在等待网络的读写
网友评论