并发:发生死锁和处理死锁

1、什么是死锁?

死锁指一组互相竞争系统资源的进程/线程永久性地阻塞 (以下线程同进程)。当一组线程中的每个线程都在请求某些资源,而这组线程中被阻塞的其他线程已经占用了这些资源,没有其他任何线程会再释放出这些资源,于是就发生了死锁,死锁是永久的。

2、发生死锁的条件

死锁有三个必要条件:

互斥。一次只有一个线程可以使用一个资源。

占有且等待。当一个线程已占用了某些资源,在请求等待其他资源的时候,不释放已占用的资源。

不可抢占。其他线程不能强行抢占线程已经占用的资源。

这三个条件是发生死锁的必要条件,而非充分条件。要产生死锁还需要第四个条件:

循环等待。存在一个闭合的线程链,每个线程至少占有线程链中下一个线程所需的资源。

这四个条件构成了死锁的充分必要条件

3、处理死锁的方法

3.1 死锁预防

死锁预防是试图设计一种方式来破坏构成死锁的一个条件。

1)互斥。这个条件是不能禁止的,如果需要对资源进行互斥访问,那么操作系统就必须支持互斥。

2)占有且等待。要求线程一次性地请求所有需要的资源,并阻塞这个线程直到所有请求都能满足。

使用账户转账的例子说明。示例代码1:

//资源分配器类,用于分配各账户进行转账操作时所需申请的锁资源
class Allocator{
   
  //list容器保存资源对象
  private List<Object> als = new ArrayList<>();
  
  private Allocator(){
   
    
  }
  //单例模式,所有线程使用同一个资源分配器
  private static Allocator instance = new Allocator();
  
  public static Allocator getInstance(){
   
    return instance;
  }
  
  //申请资源,也就是本账户对象this和目标账户对象target这两把锁
  synchronized public boolean apply(Object from, Object to){
   
    //当一个线程申请这两个资源时,发现容器中已经存在其中一个对象,
    //说明其他对象已经占用了至少一个对象,那本次申请就不成功,因为不能一次申请全部所需资源
    if(als.contains(from) || als.contains(to)){
   
      <
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值