【Java】什么是死锁?怎么避免死锁的发生?

死锁的概念

死锁是指在并发系统中,两个或多个进程无限期地等待对方持有的资源,导致所有进程无法继续执行的一种状态。在死锁发生时,每个进程都在等待其他进程释放资源,而这些资源却无法被释放,造成了一个相互等待的循环。这种情况下,系统无法进一步发展,进程无法继续执行,需要人工干预才能解决问题。

死锁只有在同时满足四个条件才会发生:

  • 互斥条件
  • 请求与保持条件
  • 不可剥夺条件
  • 循环等待条件

产生死锁的四大条件

互斥条件

在一段时间内某些资源只能被一个线程占用,若还有其他线程请求资源,请求者只能等待直到占有资源的线程使用完毕释放。

比如线程A获得了资源1,此时线程B想要获取资源1,但是资源1已经被线程A占有了,那么线程B就只能等待线程A使用完以后才能获取资源1。

请求与保持条件

线程已经保持至少一个资源,但又提出了新的资源请求,而该资源已经被其他的线程所占用,此时请求线程发生阻塞,但又对自己所占用的资源保持不放。

比如线程A获得了资源1,线程B获得了资源2,此时线程A想要获取资源2,但是会进入阻塞,因为资源2已经被线程B获得了,在这个等待过程中线程A并不会释放自己的资源1。

不可剥夺条件

线程已获得的资源,在没有使用完不能被剥夺,只能在使用完后自己释放。

比如线程A获得了资源1,在没有使用完的情况下是不会被其他想要获取资源1的线程释放的,其他想要获取资源1的线程只能等到线程A使用完资源1后自动释放再去获取资源1。

循环等待条件

多个进程之间形成一种循环等待资源的关系。

比如线程A获得了资源1,线程B获得了资源2,此时线程A想要请求资源2,而线程B想要请求资源1,此时就形成了一种循环等待的条件。

如何避免死锁

  1. 预防死锁:设计阶段就采取措施,破坏死锁的发生条件。比如,只要破坏其中一个条件,如破坏循环等待条件,就可以避免死锁的发生。
  2. 避免死锁:通过资源分配策略,避免系统陷入不可解的死锁状态。例如,银行家算法可以根据资源需求的安全性进行资源分配,保证系统不会进入死锁状态。
  3. 检测死锁:这种方法无需事先采取任何限制性措施,允许进程在运行过程中发生死锁。但可通过检测机构及时的检测出死锁的发生,然后采取适当措施,把进程从死锁中解脱出来。
  4. 解除死锁:当检测到系统中已发生死锁时,就采取相应措施,将进程从死锁状态中解脱出来。常用的方法是撤销一些进程,回收它们的资源,将它们分配给已处于阻塞状态的进程,使其能继续运行。

预防死锁

预防死锁就是破坏产生死锁四大条件中的一个或者多个,避免发生死锁,但其中的互斥条件是非共享设备所必需的条件,因此不能破坏,所有破坏的主要是其余三个。

破坏请求与保持条件

当一个进程在请求资源时,不能持有不可抢占的资源。

第一种实现方式

所有进程在开始运行之前,必须一次性地申请其在整个过程中所需的全部资源。此时若系统有足够的资源分配给某进程,便可把其所需的所有资源分配给它。这样,该进程在整个运行期间,遍不会再提出资源要求,从而破坏了“请求”条件。系统在分配资源时,只要有一种资源不能满足进程的要求,即使其他所需的各资源都空闲也不分配给该进程,而让该进程等待。由于该进程在等待期间未占有任何资源,于是破坏了“保持”条件,从而可以预防死锁的发生。

这种方式的缺点极为明显,就是资源严重浪费,降低了资源利用率,进程在开始运行时就一次性地占用了整个运行过程所需的全部资源,其中有些资源可能仅在运行初期或运行快结束时才使用,甚至根本不使用。

第二种实现方式

该实现是对第一种实现的改进,它允许一个进程只获得运行初期所需的资源后,便开始运行。进程运行过程中再逐步释放已分配给自己的、且已用毕的全部资源。然后再请求新的所需资源。

破坏不可抢占条件

当一个已经保持了某些不可被抢占资源的进程,提出新的资源请求而不能得到满足时,它必须释放已经保持的所有资源,待以后需要时再重新申请。该方法实现起来比较复杂,且需付出很大的代价。

破坏循环等待条件

通过对资源进行排序或者限制资源请求的顺序,可以避免形成循环等待。

可以采用顺序资源分配法,给系统中的资源编号,规定每个进程必须按照编号递增的方式请求资源,编号相同的资源(同类资源)一次申请完。

原理:一个进程只有已占有小编号的资源时,才有资格申请大编号的资源,已持有大编号的资源是不会去申请小编号资源的,从而就不会出现循环等待的现象。

缺点:
  • 不方便增加新的设备,因为要重新分配编号。
  • 进程实际使用资源的顺序可能和编号顺序不同,造成资源浪费。
  • 必须按照编号申请资源,编程麻烦。

资料参考:《死锁的概念以及如何避免死锁》

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值