jstack找到java死锁线程信息

首先熟悉一下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.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容