java面试-死锁产生、定位分析和修复

死锁发生:两个或多个线程之间,互相持有对方需要的锁,而永久处于阻塞状态

一、手写死锁代码:

public class DeadLockSample extends Thread {
    private String first;
    private String second;

    public DeadLockSample(String name, String first, String second) {
        super(name);
        this.first = first;
        this.second = second;
    }


    @Override
    public void run() {
        synchronized (first) {
            System.out.println(this.getName() + " obtained:" + first);
            try {
                TimeUnit.SECONDS.sleep(1);
                synchronized (second){
                    System.out.println(this.getName() + " obtained:" + second);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public static void main(String[] args) throws InterruptedException{
        String lockA = "lockA";
        String lockB = "lockB";
        DeadLockSample deadLockSample1 = new DeadLockSample("thread1",lockA,lockB);
        DeadLockSample deadLockSample2 = new DeadLockSample("thread2",lockB,lockA);
        deadLockSample1.start();
        deadLockSample2.start();
        deadLockSample1.join();
        deadLockSample2.join();

    }
}

 

二、死锁产生的四个条件:
互斥:共享资源X和Y只能被一个线程占用
占有且等待:线程T1已经获取共享资源X,在等待共享资源Y的时候,不释放共享资源X
不可抢占:其他线程不能强行抢占线程T1占有的资源
循环等待:线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源,这就是循环等待。

三、死锁定位:

jps -l

jstack pid

Found one Java-level deadlock:
=============================
"thread2":
  waiting to lock monitor 0x00007fa34c016148 (object 0x00000007957fc7d0, a java.lang.String),
  which is held by "thread1"
"thread1":
  waiting to lock monitor 0x00007fa34c016358 (object 0x00000007957fc808, a java.lang.String),
  which is held by "thread2"

Java stack information for the threads listed above:
===================================================
"thread2":
        at com.example.demo.javaLession.lession18.DeadLockSample.run(DeadLockSample.java:41)
        - waiting to lock <0x00000007957fc7d0> (a java.lang.String)
        - locked <0x00000007957fc808> (a java.lang.String)
"thread1":
        at com.example.demo.javaLession.lession18.DeadLockSample.run(DeadLockSample.java:41)
        - waiting to lock <0x00000007957fc808> (a java.lang.String)
        - locked <0x00000007957fc7d0> (a java.lang.String)

Found 1 deadlock.

四、预防死锁:

破坏占有且等待条件:保证一次申请所有的资源。

破坏不可抢占条件:synchronized无法做到,synchronized申请不到资源直接进入阻塞状态。

java.util.concurrent Lock可以解决此问题

破坏循环等待条件:需要对资源进行排序,然后按序申请资源

五、修复死锁

发生死锁无法在线解决,必须重启,修正程序本身的问题

 

posted @ 2019-06-22 18:47  与君共舞  阅读(831)  评论(0编辑  收藏  举报