jstack是java虚拟机自带的一种堆栈跟踪工具,jstack用于打印出给定的java进程ID或远程调试服务的java堆栈信息。
想要通过jstack命令来分析线程的情况的话,首先要知道线程都有哪些状态,下面这些状态是我们使用jstack命令查看线程堆栈信息时可能会看到的线程的几种状态。
NEW,未启动的。不会出现在Dump中。
RUNNABLE,在虚拟机内执行的。运行中状态,可能里面还能看到locked字样,表明它获得了某把锁。
BLOCKED,受阻塞并等待监视器锁。被某个锁(synchronizers)給block住了。
WATING,无限期等待另一个线程执行特定操作。等待某个condition或monitor发生,一般停留在park(), wait(), sleep(),join() 等语句里。
TIMED_WATING,有时限的等待另一个线程的特定操作。和WAITING的区别是wait() 等语句加上了时间限制 wait(timeout)。
TERMINATED,已退出的。
下面 我们写一个死锁的代码,然后查看用jstack命令来调试:
package test;
/**
* 死锁的问题
*/
public class DeadLockDemo {
private static String A = "A";
private static String B = "B";
public static void main(String[] args) {
deadLock();
}
private static void deadLock(){
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (A){
try {
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
synchronized (B){
System.out.println("A");
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (B){
synchronized (A){
System.out.println("B");
}
}
}
});
t1.start();
t2.start();
}
}
将线程运行信息打印到指定文件位置
jstack 969 > test.txt
查看打印的信息
2019-04-25 18:44:17
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.211-b12 mixed mode):
"Attach Listener" #13 daemon prio=9 os_prio=31 tid=0x00007febb7005000 nid=0x3d03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"DestroyJavaVM" #12 prio=5 os_prio=31 tid=0x00007febb7883000 nid=0x2503 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Thread-1" #11 prio=5 os_prio=31 tid=0x00007febb7882800 nid=0x4203 waiting for monitor entry [0x0000700008d8d000]
java.lang.Thread.State: BLOCKED (on object monitor)
at test.DeadLockDemo$2.run(DeadLockDemo.java:39)
- waiting to lock <0x00000007956a4728> (a java.lang.String)
- locked <0x00000007956a4758> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
"Thread-0" #10 prio=5 os_prio=31 tid=0x00007febb8083000 nid=0x3b03 waiting for monitor entry [0x0000700008c8a000]
java.lang.Thread.State: BLOCKED (on object monitor)
at test.DeadLockDemo$1.run(DeadLockDemo.java:27)
- waiting to lock <0x00000007956a4758> (a java.lang.String)
- locked <0x00000007956a4728> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
"Service Thread" #9 daemon prio=9 os_prio=31 tid=0x00007febb8844800 nid=0x4403 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x00007febb7095000 nid=0x3703 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x00007febb7094800 nid=0x3503 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x00007febb8009000 nid=0x3303 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x00007febb7881800 nid=0x3203 runnable [0x0000700008678000]
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 <0x00000007957097b8> (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 <0x00000007957097b8> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007febb7832800 nid=0x4603 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007febb8008000 nid=0x2f03 in Object.wait() [0x0000700008472000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000795588ed0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
- locked <0x0000000795588ed0> (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=31 tid=0x00007febb8809800 nid=0x2d03 in Object.wait() [0x000070000836f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000795586bf8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:502)
at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
- locked <0x0000000795586bf8> (a java.lang.ref.Reference$Lock)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"VM Thread" os_prio=31 tid=0x00007febb8805000 nid=0x5103 runnable
"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007febb8004800 nid=0x1c07 runnable
"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007febb8005000 nid=0x2a03 runnable
"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007febb7018800 nid=0x2b03 runnable
"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007febb8005800 nid=0x2c03 runnable
"VM Periodic Task Thread" os_prio=31 tid=0x00007febb8845800 nid=0x3a03 waiting on condition
JNI global references: 15
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007febb880f758 (object 0x00000007956a4728, a java.lang.String),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x00007febb880ce18 (object 0x00000007956a4758, a java.lang.String),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at test.DeadLockDemo$2.run(DeadLockDemo.java:39)
- waiting to lock <0x00000007956a4728> (a java.lang.String)
- locked <0x00000007956a4758> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
"Thread-0":
at test.DeadLockDemo$1.run(DeadLockDemo.java:27)
- waiting to lock <0x00000007956a4758> (a java.lang.String)
- locked <0x00000007956a4728> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.