死锁详解

死锁的定义

所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,每个进程持有某种资源而又都等待着别的进程释放它或它们现在保持着的资源,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进的情况,称这一组进程产生了死锁。

死锁的原因

1.竞争资源

2.进程间推进顺序非法

死锁的条件(四个必要条件)

1.互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。

2.请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。

3.不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。

4.环路等待条件:在发生死锁时,必然存在一个进程–资源的环形链。

死锁的解决方法

1.预防死锁(通过设置某些限制条件,以破坏产生死锁的四个条件中的一个或者几个,来防止发生死锁)

理论上

1.资源一次性分配:一次性分配所有资源,这样就不会再有请求了:(破坏请求条件)

是由设备的固有特性所决定的,不仅不能改变,相反还应加以保证。故这个条件不能用于预防。

共享资源能共享是系统本身设定。

2.只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请保持条件)

其特点为:资源严重浪费,进程延迟进行。

3.可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)

此方法实现比较复杂,且要付出很大代价;此外,还因为反复地申请和释放资源,而使进程的执行无限地推迟,延长了周转时间,增加了系统的开销,降低了系统吞吐量。

4.资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)

实际上

1、以确定的顺序获得锁

2、超时放弃

使用synchronized关键词提供的内置锁时,只要线程没有获得锁,那么就会永远等待下去,然而Lock接口提供了boolean tryLock(long time, TimeUnit unit) throws InterruptedException方法,该方法可以按照固定时长等待锁,因此线程可以在获取锁超时以后,主动释放之前已经获得的所有的锁。通过这种方式,也可以很有效地避免死锁

2.避免死锁(系统在分配资源时根据资源的使用情况提前作出预测,从而避免死锁的发生)

避免死锁与预防死锁的区别在于:

预防死锁是设法至少破坏产生死锁的必要条件之一,严格地防止死锁的出现。

避免死锁,它是在进程请求分配资源时,采用某种算法(银行家算法)来预防可能发生的死锁:系统在进行资源分配之前预先计算资源分配的安全性。若此次分配不会导致系统进入不安全的状态,则将资源分配给进程;否则,进程等待。

在避免死锁(或银行家算法)中必须谈到两种系统状态:

①安全状态,指系统能按照某种顺序,为每个进程分配所需的资源,直至最大需求,使得每个进程都能顺利完成。

②非安全状态:即在某个时刻系统中不存在一个安全序列,则称系统处于不安全状态或非安全状态。

总结:虽然并非所有不安全状态都是死锁状态,但当系统进入不安全状态后,便有可能进入死锁状态;反之只要系统处于安全状态,系统便可避免进入死锁状态。因此,避免死锁的实质是如何使系统不进入不安全状态。

银行家算法:首先需要定义状态和安全状态的概念。系统的状态是当前给进程分配的资源情况。因此,状态包含两个向量Resource(系统中每种资源的总量)和Available(未分配给进程的每种资源的总量)及两个矩阵Claim(表示进程对资源的需求)和Allocation(表示当前分配给进程的资源)。安全状态是指至少有一个资源分配序列不会导致死锁。当进程请求一组资源时,假设同意该请求,从而改变了系统的状态,然后确定其结果是否还处于安全状态。如果是,同意这个请求;如果不是,阻塞该进程知道同意该请求后系统状态仍然是安全的。(具体可查看 银行家算法解析说明

3.检测死锁(允许系统在运行的过程中产生死锁,但是,系统中有相应的管理模块可以及时检测出已经产生的死锁,并且精确地确定与死锁有关的进程和资源,然后采取适当措施,清除系统中已经产生的死锁)

(1)首先为每个进程和每个资源指定一个唯一的号码;

(2)然后建立资源分配表和进程等待表。

(3)检查系统中由进程和资源构成的有向图是否构成一个或多个环路,若是,则存在死锁,否则不存在。其实质是确定是否存在环路等待现象,一但发现这种环路便认定死锁存在,并识别出该环路涉及的有关进程,以供系统采取适当的措施来解除死锁。

4.解除死锁

当发现有进程死锁后,便应立即把它从死锁状态中解脱出来,常采用的方法有:

剥夺资源:从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态;

撤消进程:可以直接撤消死锁进程或撤消代价最小的进程,直至有足够的资源可用,让死锁状态消除为止;所谓代价是指优先级、运行代价、进程的重要性和价值等。

Original: https://www.cnblogs.com/chafry/p/16700904.html
Author: 忧愁的chafry
Title: 死锁详解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/617148/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 阻塞非阻塞和同步异步的区分 参考一些书籍

    编程中一直对这两个概念不是很理解,在网上搜了很多资料大概描述的其实都很模糊,有时候还自相矛盾,很容易搞混,这里说一下我对这两个概念的理解。首先看一下相关技术书籍对这两个概念的描述,…

    Java 2023年6月6日
    092
  • 9、线程礼让yield

    线程礼让: 1、让正在执行的线程为暂停,但不阻塞; 2、让状态转为就绪 3、让cpu重写调度,礼让不一定成功; Thread.currentThread()获取当前线程的引用 Or…

    Java 2023年6月8日
    071
  • 6.Springboot切换日志框架

    1.Springboot默认使用logback2.切换到log4j2 org.springframework.bootspring-boot-starter-web spring-…

    Java 2023年6月13日
    092
  • C# 多线程详解 Part.02(UI 线程和子线程的互动、ProgressBar 的异步调用)

    我们先来看一段运行时会抛出 InvalidOperationException 异常的代码段: 微软在子线程修改 UI 线程的控件值时给出的安全限制方案为: 在 VS2005 或者…

    Java 2023年5月29日
    088
  • 通过OptaPlanner优化 COVID-19 疫苗接种预约安排(1)-无视频版

    近两年来的冠疫情使得社会工作生活备受影响。接种疫苗是其中一种有效减缓疫情的途径之一,但病毒的传染性,疫苗接种的规律性,及接种人群数量及分布等特性,对接种活动的计划安排提出了巨大挑战…

    Java 2023年6月16日
    079
  • 聊聊webservice

    webservice这个东西已经是一个比较旧的技术了,可能很多人都没听说过,乍一听是不是跟websocket有关呀,哈哈哈,其实压根就是两个东西; 我对webservice的理解是…

    Java 2023年6月6日
    083
  • (读书笔记)基于CMMI的软件工程及实训指导 第13-16章

    一、软件测试 软件测试是为了发现程序中的错误而执行的过程。测试只能证明软件有错,而不能保证软件程序没错。 1. 软件版本 Alpha版 公司内测版本 Beta版 对外公测版本 发布…

    Java 2023年6月5日
    0105
  • 教学日志:javaSE-面向对象2

    一、局部变量和成员变量 package class4.oop1; /** * @Auther: Yu Panpan * @Date: 2021/12/10 – 12 – 10 – …

    Java 2023年6月5日
    0100
  • MyBatisCodeHelperPro激活方法(有效方法)

    注意事项我的idea是2021.2.1的,新版本的idea我也不清楚。我这个版本是可以的。 ​编辑 1、下载插件 ​编辑 这是插件下载的地址: MybatisCodeHelperN…

    Java 2023年6月13日
    0125
  • 5、接口

    接口 接口(interfance)就是一个规范,定义的成员默认就是public static fianl ,定义的方法默认是public abstract 其他类实现(implem…

    Java 2023年6月6日
    087
  • Spring(十六):声明式事务管理

    一、什么是事务 事务就是一系列的业务逻辑的操作,必须要全部执行成功,否则每个操作所执行的内容都要撤销。 二、事务的四大特性 1.原子性(atomicity):事务虽然有一系列的操作…

    Java 2023年6月15日
    093
  • @EqualsAndHashCode(callSuper = false) 解释

    当我们的pojo使用@Data注解时,@Data默认包含的是:@EqualsAndHashCode(callSuper = false),但是我们的pojo有继承父类,我们可能需要…

    Java 2023年6月7日
    076
  • 如何保持Redis和MySQL数据一致?

    认识MySQL和Redis的数据一致性问题 解决 Redis 与 MySQL 数据一致性问题 MySQL和Redis保持数据一致性的解决方案总结 Original: https:/…

    Java 2023年6月15日
    099
  • There is no getter for property named ‘id’ in ‘class java.lang.Integer

    There is no getter for property named ‘id’ in ‘class java.lang.Integer 问…

    Java 2023年5月29日
    060
  • 7、System类

    exit 退出当前程序 System.out.println("ok1"); //1. exit(0) 表示程序退出 //2. 0 表示一个状态,正常的状态 S…

    Java 2023年6月7日
    079
  • 大白话之数据库事务

    本文摘自我的公众号: 陶朱公Boy。欢迎大家关注! 关注我: 上述文章摘自作者的公众号:陶朱公Boy 公众号内容包括:以下系列文章,欢迎大家关注。也欢迎大家加我微信(公众号有联系方…

    Java 2023年6月15日
    084
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球