线程死锁排查

阅读 75

2022-04-30

造成死锁的原因

死锁是指两个或两个以上的线程在执行过程中,因争夺锁而造成的一种互相等待的现象,若无外力作用,它们都将一直等待下去。

造成死锁的示例

public class DeadlockTest {
    private final Object lock1 = new Object();
    private final Object lock2 = new Object();

    public void lock() {
        Thread t1 = new Thread(() -> {
            try {
                synchronized (lock1) {
                    System.out.println("t1:获取lock1成功");
                    Thread.sleep(2000);

                    synchronized (lock2) {
                        System.out.println("t1:获取lock2成功");
                        Thread.sleep(2000);
                    }
                }
            } catch (InterruptedException e) {
                System.out.println("t1:中断");
            }
        });

        Thread t2 = new Thread(() -> {
            try {
                synchronized (lock2) {
                    System.out.println("t2:获取lock2成功");
                    Thread.sleep(2000);

                    synchronized (lock1) {
                        System.out.println("t2:获取lock1成功");
                        Thread.sleep(2000);
                    }
                }
            } catch (InterruptedException e) {
                System.out.println("t2:中断");
            }
        });

        t1.start();
        t2.start();
    }

    public static void main(String[] args) {
        DeadlockTest deadlock = new DeadlockTest();
        deadlock.lock();
    }
}

如何避免死锁?

  1. 尽量不要用多个锁。
  2. 按照同一个顺序获取锁。
  3. 使用重入锁,通过重入锁的中断和限时等待规避死锁。

注意:死锁的线程不占用CPU。

定位死锁

  1. 使用jps命令找到JVM进程
    在这里插入图片描述
  2. 然后使用jstack -l PID命令查看进程中的线程,查找是否有两个或者多个线程在相互获取对象持有的锁。
    在这里插入图片描述
    在jstack输出信息的最后面,有死锁相关的信息
    在这里插入图片描述
    推荐一个经常用来分析线程dump文件的在线分析工具:FastThread

精彩评论(0)

0 0 举报