死锁的成因和解决方案

1.什么是死锁

死锁是多线程代码中常常出现的bug

当想给线程加锁时发现线程的上次的锁还没有及时释放,导致加锁不上

死锁分别有以下几种情况

1.一个线程两把锁:

如果是可重入锁的话是没有问题的,但是如果是不可重入锁的话就会死锁了

synchronized(this){
//synchronized是可重入锁,所以不会死锁
//但是如果是其他锁,放在代码块里,后入的锁需要等到上一个锁释放才能锁上,但是上一个锁的释放又依赖于后入的锁的释放,就好像这个代码块一样,前面的代码块需要必须执行完才能进入第二个代码块,但是前面的代码块执行又依赖于第二个代码块的执行

synchronized(this){}
}

2.两个线程两把锁

线程1获取到了锁A

线程2获取到了锁B

如果线程1尝试获取锁B或者线程2尝试获取锁A,这时候就会死锁

就好比,小孩子打架,小明拿着娃娃想要换小红的超人,两者都说你给我我就给你,结果两个都不肯,这是后就一直僵持不下了.

3.N个线程M把锁:

这时候引出一个情景:哲学家就餐问题:(概率问题)

总结一下形成死锁的四个必要条件:(锁的基本特点)

1.互斥使用,1线程拿到A锁,其他线程就不能获取A锁

2.不可抢占:1线程拿到A锁,其他线程就只能阻塞等待锁A在1线程中释放,不能强行把他抢占

3.请求和保持:1线程拿到A锁后,就会一直持有获取锁这个状态,知道说主动释放.

4.循环等待,1线程等待2线程,2线程又尝试等待1线程.

2.死锁的解决方案

打破等待循环:针对多把锁进行锁编号,并按一定的顺序获取

比如:锁1,2,3,4,5.......约定在获取多把锁的时候要明确获取锁的顺序是从小到大的顺序

线程要拿到1,2两把锁,就先获取1再获取2

要拿到2,4这两把锁,就先获取2,然后再获取4

这种方法就是,对锁编号,并且按顺序加锁,从而打破循环等待

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值