首先熟悉一下jstack命令的用法,如下图:
Usage:
jstack [-l] <pid>
(to connect to running process)
jstack -F [-m] [-l] <pid>
(to connect to a hung process)
jstack [-m] [-l] <executable> <core>
(to connect to a core file)
jstack [-m] [-l] [server_id@]<remote server IP or hostname>
(to connect to a remote debug server)
Options:
-F to force a thread dump. Use when jstack <pid> does not respond (process is hung)
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
-h or -help to print this help message
编写模拟死锁的java代码,如下
@Slf4j
public class DeadLockMocker implements Runnable {
/**
* 标识
* flag = 1 , 占用资源L1去获取L2
* flag = 0 , 占用资源L2去获取L1
*/
public boolean flag = false;
/**
* 声明两个资源对象用来获取资源锁
*/
public static Object L1 = new Object();
public static Object L2 = new Object();
public static void mock() {
DeadLockMocker deadLock1 = new DeadLockMocker();
DeadLockMocker deadLock2 = new DeadLockMocker();
deadLock1.flag = true;
deadLock2.flag = false;
Thread thread1 = new Thread(deadLock1, "deadlock-mock-thread-1");
Thread thread2 = new Thread(deadLock2, "deadlock-mock-thread-2");
thread1.start();
thread2.start();
}
@Override
public void run() {
log.info("flag: {}", flag);
// deadLock2占用资源o1,准备获取资源o2
if (flag) {
log.info("准备获取到资源 L1");
synchronized (L1) {
log.info("获取到资源 L1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("准备获取到资源 L2");
synchronized (L2) {
log.info("获取到资源 L2");
}
}
} else if (!flag) {
log.info("准备获取到资源 L2");
synchronized (L2) {
log.info("获取到资源 L2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("准备获取到资源 L1");
synchronized (L1) {
log.info("获取到资源 L1");
}
}
}
}
}
使用jps找到执行代码的进程ID,启动类名为Application的进程ID为20474
➜ /Users/tandong >jps
20832 Jps
87603 RemoteMavenServer
20473 Launcher
20474 Application
87050
然后通过jstack命令找到java进程中死锁的线程锁信息,执行jstack -l 95769,如下图(只贴了死锁的线程信息),可以看到模拟死锁的两个线程deadlock-mock-thread-1和deadlock-mock-thread-2:
Found one Java-level deadlock:
=============================
"deadlock-mock-thread-2":
waiting to lock monitor 0x00007fecc11de268 (object 0x00000007702b9fb0, a java.lang.Object),
which is held by "deadlock-mock-thread-1"
"deadlock-mock-thread-1":
waiting to lock monitor 0x00007fecc11ab318 (object 0x00000007702b9fc0, a java.lang.Object),
which is held by "deadlock-mock-thread-2"
Java stack information for the threads listed above:
===================================================
"deadlock-mock-thread-2":
at com.tandong.mock.DeadLockMocker.run(DeadLockMocker.java:75)
- waiting to lock <0x00000007702b9fb0> (a java.lang.Object)
- locked <0x00000007702b9fc0> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
"deadlock-mock-thread-1":
at com.tandong.mock.DeadLockMocker.run(DeadLockMocker.java:58)
- waiting to lock <0x00000007702b9fc0> (a java.lang.Object)
- locked <0x00000007702b9fb0> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
Found 1 deadlock.