一. 模拟死锁代码:

package com.xh.utils;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * @author wen
 * @apiNote DeadLock
 * @since 2021-12-02
 */
public class DeadLockJvm {
    private static final Lock LOCK1 = new ReentrantLock();
    private static final Lock LOCK2 = new ReentrantLock();
    public static void testThread01() {
        LOCK1.lock();
        try {
            Thread.sleep(1_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("testThread01-1");
        LOCK2.lock();
        System.out.println("testThread01-2");
        LOCK2.unlock();
        LOCK1.unlock();
    }
    public static void testThread02() {
        LOCK2.lock();
        System.out.println("testThread02-2");
        LOCK1.lock();
        System.out.println("testThread02-1");
        LOCK1.unlock();
        LOCK2.unlock();
    }
    public static void start() {
        new Thread(DeadLockJvm::testThread01).start();
        new Thread(DeadLockJvm::testThread02).start();
        try {
            Thread.sleep(1_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        start();
    }
}


package com.xh.utils;
/**
 * @author wen
 * @apiNote DeadLock
 * @since 2021-12-02
 */
public class DeadLockSys {
    private static final Object OBJECT1 = new Object();
    private static final Object OBJECT2 = new Object();
    public static void testThread01() {
        synchronized (OBJECT1) {
            try {
                Thread.sleep(1_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("testThread01-1");
            synchronized (OBJECT2) {
                System.out.println("testThread01-2");
            }
        }
    }
    public static void testThread02() {
        synchronized (OBJECT2) {
            System.out.println("testThread02-2");
            synchronized (OBJECT1) {
                System.out.println("testThread02-1");
            }
        }
    }
    public static void start() {
        new Thread(DeadLockSys::testThread01).start();
        new Thread(DeadLockSys::testThread02).start();
        try {
            Thread.sleep(1_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        start();
    }
}


二. 运行代码:

1. 使用 jps 工具查看运行中的java进程信息:

jps -l

                                

进程ID  14667


2. 使用 jstack 工具查看线程信息:

jstack -l 14667 | more

按下/enter,可以进行翻阅

在最后我们可以看到死锁的线程以及堆栈信息;


3. 也可以将整合线程信息输出到文件,然后用文本编辑器打开翻阅:

 jstack -l 14667 > jstack-thread-info.log

可以通过关键字搜索:Java-level deadlock,快速定位是否出现死锁。



三. 查看占用CPU资源高的线程信息:

      1. top查看占用CPU资源高的进程;

      2. top -Hp   或者 ps -mp -o THREAD, tid, time  查看该进程中占用CPU资源高的线程TID;

      3. printf "%x"  <TID> 将线程ID转16进制,TIDx16;

      4. jstack | grep < TIDx16> -A60  打印线程执行信息前60行:  

      5. 查看前后代码逻辑,找出CPU资源占用高的逻辑;