死锁(DeadLock)是指两个或多个计算单元(进程、线程或协程),都在等待对方释放资源,但没有人提出释放资源,从而造成一种阻塞的现象是称为死锁。例如,线程1在拥有锁A的情况下尝试获取锁B,线程2在拥有锁B的情况下尝试获取锁A,这样双方就进入了相互阻塞等待的情况,如下图所示:deadlock代码实现如下:importjava.util.concurrent.TimeUnit;publicclassDeadLockTest{publicstaticvoidmain(String[]args){ObjectlockA=newObject();对象锁B=新对象();//创建线程1Threadt1=newThread(()->{//1.占用锁Asynchronized(lockA){System.out.println("Thread1:GetlockA.");//休眠1s(让线程2有时间启动占用锁B)try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}//2.获取线程2的锁Bsynchronized(lockB){System.out.println("线程1:获得了锁B。");}}});t1.start();//创建线程2Threadt2=newThread(()->{//1.占用锁Bsynchronized(lockB){System.out.println("Thread2:获取锁B.");//休眠1s(保证线程1有足够的时间获取锁A)try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}//2.获取线程1的锁Asynchronized(lockA){System.out.println("Thread2:getlockA.");}}});t2.start();}}执行上面的程序结果如下图所示:从上面的结果可以看出,线程1和线程2都在等待对方释放锁,这就造成了死锁问题。死锁产生的原因死锁的产生需要满足以下四个条件:互斥条件:指独占分配资源的运行单元(进程、线程或协程),也就是说一个锁资源只能被其占用一段时间内一个操作单元。请求和持有条件:指计算单元已经保留了至少一个资源,但它又提出新的资源请求,该资源已经被其他计算单元占用。此时,请求计算单元被阻塞,但它并没有放过它已经获得的其他资源。非剥夺条件:指计算单元获得的资源,在用完之前不能被剥夺。循环等待条件:发生死锁时,必然存在计算单元和资源的循环链,即计算单元在等待另一个计算单元占用的资源,而另一方在等待自己占用的资源,导致循环等待案例。只有同时满足以上四个条件,才会发生死锁。解决死锁死锁需要满足以上四个必要条件,那么我们只需要改变其中的一个或多个条件就可以解决死锁问题,比如我们可以通过修改获取锁条件的顺序来改变循环等待。在修改获取锁顺序之前,程序的执行流程如下:①表示先执行,②表示后执行。改变锁获取顺序后的执行过程如下:此时线程1和线程2获取锁的顺序是一样的,都是先获取锁A,再获取锁B。执行过程如下:线程1先获取锁A;线程1获取锁B;线程1释放锁B;线程1释放锁A;线程2获取锁A;线程2获取锁B;线程2释放锁B;线程2锁A被释放。对应的实现代码如下:importjava.util.concurrent.TimeUnit;classDeadLockTest{publicstaticvoidmain(String[]args){对象锁B=新对象();//创建线程1Threadt1=newThread(()->{//1.获取锁Asynchronized(lockA){System.out.println("线程1:获取锁A.");//休眠1stry{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}//2.同步获取锁B(lockB){System.out.println("线程1:获取锁B。");System.out.println("线程1:释放锁B。");}System.out.println("线程1:释放锁A。");}});t1.start();//创建线程2Threadt2=newThread(()->{try{TimeUnit.SECONDS.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}//1.GetlockAsynchronized(lockA){System.out.println("Thread2:GetlockA.");//2.Getlocksynchronized(lockB){System.out.println("Thread2:Getlock乙。");System.out.println("线程2:释放锁B。");}System.out.println("线程2:释放锁A。");}});t2.start();}}上述程序的执行结果如下图所示:总结死锁是指两个或多个计算单元(进程、线程或协程)相互等待释放资源,但都没有提前释放资源,从而造成阻塞现象称为死锁。死锁需要同时满足四个条件:互斥条件、请求和保持条件、不可让渡条件、循环等待条件,所以我们只需要销毁其中一个或多个条件即可解决死锁问题,是非自己评,名誉别人评,得失算。公众号:Java面试真题解析面试合集:https://gitee.com/mydb/interview
