什么是死锁
死锁出现的条件主要是资源互斥、占有并等待、非抢占、循环等待。
 当出现两个线程对不同的资源进行获取的时候,A持有资源1,去获取资源2,B持有资源2,去获取资源1,就回出现死锁。
 
如何排查死锁
public class DealLock {
    private Object objA = new Object();
    private Object objB = new Object();
    public void runA() throws InterruptedException {
        synchronized (objA) {
            System.out.println("获取到A锁,等待获取B锁");
            Thread.sleep(1000);
            synchronized (objB) {
                System.out.println("A、B都获取到了");
            }
        }
    }
    public void runB() throws InterruptedException {
        synchronized (objB) {
            System.out.println("获取到A锁,等待获取B锁");
            Thread.sleep(1000);
            synchronized (objA) {
                System.out.println("A、B都获取到了");
            }
        }
    }
    public static void main(String[] args) {
        DealLock dealLock = new DealLock();
        new Thread(()-> {
            try {
                dealLock.runA();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        new Thread(()-> {
            try {
                dealLock.runB();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}
 

Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fd4a801a000 nid=0x451f in Object.wait() [0x0000000306b2a000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x0000000715588ed0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
        - locked <0x0000000715588ed0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)
"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007fd4a8013800 nid=0x3323 in Object.wait() [0x0000000306a27000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x0000000715586bf8> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
        - locked <0x0000000715586bf8> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)
"main" #1 prio=5 os_prio=31 tid=0x00007fd49e014000 nid=0x1b03 waiting on condition [0x0000000305f06000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000007156964b8> (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
        at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock(ReentrantReadWriteLock.java:943)
        at com.jia.lock.LockDemo2.main(LockDemo2.java:22)
 
区分线程状态 -> 查看等待目标 -> 对比 Monitor 等持有状态
如何预防死锁
其实就是预防、避免、检测和解除。
 尽量使用 tryLock(long timeout, TimeUnit unit) 的方法 (ReentrantLock、 ReentrantReadWriteLock),设置超时时间,超时可以退出防止死锁;
 尽量使用 Java. util. concurrent 并发类代替自己手写锁;
 尽量降低锁的使用粒度,尽量不要几个功能用同一把锁;
 尽量减少同步的代码块。
 如果可能的话,尽量避免使用多个锁,并且只有需要时才持有锁
 如果必须使用多个锁,尽量设计好锁的获取顺序
![计算机视觉与深度学习-经典网络解析-ResNet-[北邮鲁鹏]](https://img-blog.csdnimg.cn/1691cbb905da4546b4b29d7524847f0e.png)







![[JAVAee]Spring项目的创建与基本使用](https://img-blog.csdnimg.cn/034286397b35431294a9a6943f892915.png)

![[JAVAee]SpringBoot配置文件](https://img-blog.csdnimg.cn/043c06fe53d34271b4820e6b53b54ed7.png)







