Java 并发之死锁以及使用工具检测死锁

170 阅读1分钟

死锁相关

  • 详情
  • 活锁:线程持续重试一个总是失败的操作,导致无法继续执行
  • 饿死∶线程一直被调度器延迟访问其赖以执行的资源,也许是调度器先于低优先级的线程而执行高优先级的线程,同时总是会有一个高优先级的线程可以执行,饿死也叫做无限延迟

模拟死锁以及工具使用

public class DeadLockTest {
    Object lock1 = new Object();
    Object lock2 = new Object();
    public void method1(){
        //当一个线程获取到lock1后,想要再获取lock2,但是lock2可能已经被其他线程获取,就会导致该线程阻塞
        synchronized (lock1){
            synchronized (lock2){
                System.out.println("Thread-001 invoked");
            }
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public void method2(){
        //当一个线程获取到lock2后,想要再获取lock1,但是lock1可能已经被其他线程获取,就会导致该线程阻塞
        synchronized (lock2){
            synchronized (lock1){
                System.out.println("Thread-002 invoked");
            }
        }
        try {
            Thread.sleep(210);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    /*
    当两个线程分别获取到了lock1和lock2,且无法释放,就会导致死锁
     */
    public static void main(String[] args) {
        DeadLockTest deadLockTest = new DeadLockTest();
        Runnable run1 = ()->{
            while (true){
                deadLockTest.method1();
            }
        };
        Runnable run2 = ()->{
            while (true){
                deadLockTest.method2();
            }
        };
        new Thread(run1,"Thread-001").start();
        new Thread(run2,"Thread-002").start();
    }
}

使用可视化工具jvisualvm

  • shell窗口输入jvisualvm
  • 这是jdk自带的

image.png

image.png

  • 运行上述可能产生死锁的代码

image.png

  • 查看线程Dump

image.png

使用命令行查看

  • jps -l先查看产生死锁的进程ID

image.png

  • jstack 进程id检测死锁

image.png

  • 结果

image.png

  • 其实和可视化的是一样的

image.png