概念:查看jvm中 线程发生问题的几种方式,这里以死锁为例
1.jps+jstack -l [pid]
测试代码

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName DeathLockTest
 * @Description TODO
 * @Author zxr
 * @Date 2023/1/3
 */
public class DeathLockTest {
    private static Lock lock1 = new ReentrantLock();
    private static Lock lock2 = new ReentrantLock();

    public static void deathLock() {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                try {
                    lock1.lock();
                    System.out.println(Thread.currentThread().getName() + " get the lock1");
                    Thread.sleep(1000);
                    lock2.lock();
                    System.out.println(Thread.currentThread().getName() + " get the lock2");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread t2 = new Thread() {
            @Override
            public void run() {
                try {
                    lock2.lock();
                    System.out.println(Thread.currentThread().getName() + " get the lock2");
                    Thread.sleep(1000);
                    lock1.lock();
                    System.out.println(Thread.currentThread().getName() + " get the lock1");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        //设置线程名字,方便分析堆栈信息
        t1.setName("mythread-jay");
        t2.setName("mythread-tianluo");
        t1.start();
        t2.start();
    }
    public static void main(String[] args) {
        deathLock();
    }

}

使用jps查看可运行的java程序

Java查看执行线程数量 查看线程运行状态jvm_Java查看执行线程数量


前面的数值就是我们代码的进程pid

之后再通过jstack -l [pid] 查看进程的堆栈信息

jstack -l 45624

Java查看执行线程数量 查看线程运行状态jvm_死锁_02


继续往下找到出问题的地方

Java查看执行线程数量 查看线程运行状态jvm_java_03


在这里就可以看到 出问题的两个线程了,分别为:mythread-tianluo,mythread-jay;

继续往下查看 是出了啥问题。

Java查看执行线程数量 查看线程运行状态jvm_Java查看执行线程数量_04


这里可以看到线程deadlock(死锁) 了

继续看详情

Java查看执行线程数量 查看线程运行状态jvm_jvm_05


红线部分:发生死锁位置

绿线部分:可以看出是在等待一秒之后另外有另一个线程获取资源,重而产生了死锁

这里使用jps 和 jstack -l [pid] 命令查询的

也可以直接使用jconsole进行查看

2.jconsole

选择进程为:45624的

Java查看执行线程数量 查看线程运行状态jvm_Java查看执行线程数量_06


选择线程点击检测死锁

Java查看执行线程数量 查看线程运行状态jvm_java_07


能够将死锁的线程检测出来

Java查看执行线程数量 查看线程运行状态jvm_jvm_08


分别点击两个线程,看死锁发生在哪个位置,和上面看到的是否一致

Java查看执行线程数量 查看线程运行状态jvm_java_09


Java查看执行线程数量 查看线程运行状态jvm_System_10


可以看到分别为38,24 和上面检测出的是一致的。3.jvisualvm

Java查看执行线程数量 查看线程运行状态jvm_System_11


选择40268

Java查看执行线程数量 查看线程运行状态jvm_Java查看执行线程数量_12


展开查看

Java查看执行线程数量 查看线程运行状态jvm_java_13


这里已经将死锁线程检测出来了,点击右边线程dump

查看详情

Java查看执行线程数量 查看线程运行状态jvm_System_14


同样是38,24 这里分析和上面两个一样的。

在做jvm时,根据所处的开发环境做选择就可以了。还原死锁

这里还原死锁真相

挺有意思,互相获取,又都不放手,导致的死锁。

Java查看执行线程数量 查看线程运行状态jvm_java_15