案例:有一天小明和小丽两个人去玩密室逃脱,在游戏过程中分别被关到不同的房间里,小明身上有能打开小丽房间的钥匙,小丽身上有能打开小明房间的钥匙。然而小明想要出去救小丽,就得有小丽身上的钥匙,显然他得不到;小丽想要出去救小明,就得有小明身上的钥匙,显然她也做不到。这种情况在我们程序界被称为——死锁。那具体什么是死锁,为何出现,当Java多线程遇到死锁怎么办,该怎么解决呢?
一、什么是死锁?
在多线程环境中,多个进程可以竞争有限数量的资源。当进程申请资源时,如果此时没有可用资源,则进程进入等待状态。
有时,如果请求的资源被另一个等待进程占用,等待进程可能不再能够改变状态。这种情况称为死锁。
在 Java 中使用多线程可能会导致死锁问题。死锁会使程序卡住,不会继续执行。我们只能通过中止和重新启动来重新执行程序。
二、死锁的原因
• 当前线程拥有其他线程需要的资源
• 当前线程正在等待另一个线程已经拥有的资源
• 不要放弃你拥有的资源
三、死锁的必要条件
1.互斥
一个进程需要对分配的资源(如打印机)进行独占控制,即一个资源在一段时间内只被一个进程占用。此时,如果另一个进程请求该资源,则请求进程只能等待。
2.不可剥夺
进程获得的资源在用完之前不能被其他进程强行拿走,即只能由获得资源的进程自己释放(只能主动释放)。
3.请求并保留
一个进程已经拥有了至少一个资源,但是又发起了一个新的资源请求,并且该资源已经被其他进程占用了。此时,请求进程被阻塞,但它获得的资源不会被释放。
4.循环等待
意思是进程死锁发生后,进程和资源之间必然存在循环链。通俗的讲,你在等我的资源,我在等你的资源,大家都在等。
四、 死锁分类及解决方案
1.静态顺序死锁
当线程形成相互等待资源的环时,就形成了顺序死锁lock-orderingdeadlock。当多个线程试图以不同的顺序获取同一个锁时,很容易形成顺序死锁。如果所有线程都以固定的顺序来获取锁,就不会出现顺序死锁问题。
2. 动态锁顺序死锁
由于方法的输入参数是从外部传入的,虽然这两个参数在方法内部是按固定顺序锁定的,但是由于外部传递的顺序不可控,即动态锁定顺序死锁。
上面的例子告诉我们,交替获取锁会导致死锁,而锁是固定的。有时候锁的执行顺序不是很清楚,参数导致执行顺序不同。
3.协作对象之间的死锁
协作对象之间可能有多个锁的获取,但是这些多个锁的获取并不像 LeftRightDeadLock 或 transferMoney 中那么明显,而且这两个锁不一定要在同一个方法中获取。
如果在持有锁的同时调用外部方法,那么需要警惕死锁问题,因为在这个外部方法中可能会获取其他锁,或者阻塞时间过长,导致其他线程无法获取当前保持锁定时间。锁。
当Java多线程遇到死锁怎么办?在上面的两个例子中,两个锁是通过相同的方法获取的。实际上,锁不一定是通过相同的方法获得的。更多关于“Java培训”的问题,欢迎咨询千锋教育在线名师。千锋已有十余年的培训经验,课程大纲更科学更专业,有针对零基础的就业班,有针对想提升技术的好程序员班,高品质课程助力你实现java程序员梦想。