【应届面试篇】如何避免死锁?

死锁是多线程编程中的一个问题,本文详细解析了死锁的四个必要条件:互斥、占有且等待、不可抢占和循环等待,并针对每个条件提出了相应的解决策略。对于互斥,可以通过ThreadLocal避免;占有且等待可通过一次性获取所有资源解决;不可抢占则可以通过释放已占资源避免死锁;循环等待则需设定资源获取顺序。理解并实施这些策略能有效防止死锁,提高系统效率。
摘要由CSDN通过智能技术生成

如何避免死锁,那就把死锁产生的原因及必要条件避免了,问题自然而然就解决了。

那么先看死锁产生的4个必要条件

1、互斥: 某种资源一次只允许一个进程访问,即该资源一旦分配给某个进程,其他进程就不能再访问,直到该进程访问结束。
2、占有且等待: 一个进程本身占有资源(一种或多种),同时还有资源未得到满足,正在等待其他进程释放该资源。
3、不可抢占: 别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来。
4、循环等待: 存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。
当以上四个条件均满足,必然会造成死锁,发生死锁的进程无法进行下去,它们所持有的资源也无法释放。这样会导致CPU的吞吐量下降。所以死锁情况是会浪费系统资源和影响计算机的使用性能的。那么,解决死锁问题就是相当有必要的了。

如何分别解决这四个条件

互斥

互斥是非常容易解决的 使用ThreadLocal就能解决 ,互斥产生的本质原因就是多个线程要同时竞争一个资源,那么我们给每个线程都分配一个自己管理的资源不就好了。
但是使用ThreadLocal要特别注意 即时使用remove方法,否贼会引起内存泄漏。因为ThreadLocal底层是一个ThreadLocalMap,他的key是一个弱引用,而value呢确是强引用意味着value不会被GC清除,而key是弱引用如果外部没有再对key强引用的话key将被回收,被强引用的value将找不到与其对应的映射关系,那么便会发生内存泄漏。remove方法会找到这些key已经被回收的value并将他们回收。

占有且等待

破环占有且等待方法与循环等待类似,可以采取一次性获取全部需要资源的方式来解决。

不可抢占

那就是先获取锁,如果自己发现进一步申请不到其他的资源(锁),那么就释放自己已经获得的锁,那么也就不会继续死锁下去了。这个条件对应c封装的synchronized关键字同样是不行的,但是基于juc Lock写的程序还可以调用lockInterruptibly方法处理。

循环等待

这也是一个比较容易解决的,我们可以让线程对资源的加锁按照一定统一的顺序。比如如果有要AB两个资源的两个线程,那我们就都先拿A 再拿 B这样想获得B就一定要先得到A 就避免了循环等待的问题。起始说到底这种方法也是一种锁的粗化。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值