【Java并发】死锁演示

1. 死锁代码

public class DeadLockDemo {
    private static final String A = "A";
    private static final String B = "B";

    public static void main(String[] args) {
        new DeadLockDemo().deadLock();
    }

    private void deadLock() {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (A) {
                    System.out.printf("[%s]ADD LOCK TO A%n", Thread.currentThread().getName());
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (B) {
                        System.out.printf("[%s]ADD LOCK TO B%n", Thread.currentThread().getName());
                    }
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (B) {
                    System.out.printf("[%s]ADD LOCK TO B%n", Thread.currentThread().getName());
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (A) {
                        System.out.printf("[%s]ADD LOCK TO A%n", Thread.currentThread().getName());
                    }
                }
            }
        });

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

2. jstack 查看死锁

使用 jps 找到对应 java 线程的 PID (这里是 DeadLockDemo 进程),再使用 jstack dump 出进程状态,查看有无处于 BLOCKED 状态的线程

3. 避免死锁的方法

  • 避免一个线程同时获得多个锁
  • 避免一个线程再锁内同时占用多个资源,尽量保证每一个锁只会占用一个资源
  • 尝试使用定时锁,使用 lock.tryLock(timeout) 来代替使用内部锁机制
  • 对于数据库锁,加锁和解锁必须在同一个数据库链接里面,否则会出现解锁失败的情况
  • 如果出现在锁中再加锁的情况,一定要保证不同线程之间的加锁顺序一致

posted on 2022-03-09 20:16  Silgm  阅读(46)  评论(0)    收藏  举报

导航