经典面试八股文—多线程中死锁的原因与解决方案(不看后悔俩礼拜!)

1.死锁是什么

死锁:
一个线程加上了锁之后无法解锁了,属于严重的bug

2.死锁的原因

情况1:
一共有一个线程,一把锁,连续加锁两次,如果锁是不可重入锁,那么就会死锁,如果是synchronized这种可重入锁,那就没关系。
情况2:
两个线程,两把锁n1,n2,但是线程一进入锁中,线程二也进入锁中,线程1执行时,n1锁中有n2锁,线程2执行时,n2锁中有n1锁,这样就会一直死锁。
情况3:
多个线程多把锁:
典型的模型,哲学家就餐问题:
五个线程,5把锁,线程完成任务的条件是使用两把锁来完成任务,要求需要每个线程执行的时候都会使用2把锁,大部分情况下多线程环境下,不会有问题,因为有线程在执行有线程在等待着(操作系统的线程随机调度)
但是极端的情况:
五个线程,每个线程只拿到了一把锁,另一把锁被别的线程占用着,只拿一把锁又没办法完成任务,线程也没有那么智能,比如:某个线程自己放弃锁(做不到)。这样的情况下就会死锁,一直是五个线程各自拿一把锁,什么也做不了。

3.死锁的解决方案

要想解决死锁我们要知道死锁的必要条件:
1.互斥使用:
线程A使用锁的时候,线程B不能使用锁(锁的特性,没办法改)
2.不可抢占:
线程A使用锁的时候,线程B不能把线程A的锁拿过来用。(锁的特性,没办法改)
3请求和保持:
线程A在使用锁1的时候,在不释放锁1的前提下,还想使用锁2(情况2)
4.循环等待:
线程A等待线程B释放锁,线程B等待线程C释放锁,线程C等待线程A释放锁。(情况3)

只要解决其中一个死锁条件就可以解决死锁问题!!!

关于12没办法解决,我们可以从34入手
从3的角度解决死锁:
我们可以修改代码写法,让线程A想使用锁2的时候,先把锁1释放掉。
从4的角度解决死锁:
对于多个线程多个锁,我们可以对锁进行编号,让每个线程必须从最小的锁开始拿,当锁已经都被占用的时候,线程就等待锁释放,释放以后再随机调度来使用锁。
比如刚才的情况3:
我们让每个线程拿最小的锁的编号(一共5个线程,5个锁),
线程A拿锁12,线程B拿锁34,线程C拿锁5(但是执行不了任务,执行任务的前提是线程拿到2个锁)。等到AB线程执行完任务,线程们再接着随机调度,从最小的锁开始拿。这样就解决了死锁问题

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

keild

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值