首页 > 编程语言 >并发编程理论基础——死锁初阶(四)

并发编程理论基础——死锁初阶(四)

时间:2024-06-17 09:59:40浏览次数:14  
标签:初阶 账户 编程 申请 死锁 线程 等待 资源

使用细粒度锁可能会导致死锁

        死锁:一组互相竞争资源的线程因互相等待,导致永久阻塞的现象

如何产生死锁

  1. 互斥,共享资源X和Y只能被一个线程占用
  2. 占有且等待,线程T1已经取得了共享资源X,在等待共享资源Y的时候,不释放共享资源X
  3. 不可抢占,其他线程不能强行抢占线程T1占有的资源
  4. 循环等待,线程T1等待线程T2占有的资源,线程T2等待线程T1占有的资源

避免死锁(只要我们能够破坏上条的一个条件就可以成功避免)

  1. 互斥无法避免,因为锁用的就是互斥锁
  2. 对于占有且等待,可以一次性申请全部资源
  3. 对于不可抢占,占有一部分资源的线程想继续申请其他资源时,如果申请不到,可以主动释放他占有的资源,以退为进(如果申请不到是因为其他线程占用并且等待当前线程所占有的资源时,释放掉资源把他要的给他,等他执行完了咱们在执行)
  4. 对于循环等待,可以靠按序申请资源来预防。所谓按需申请是指资源是存在线性顺序的,申请的时候可以先申请资源序号小的,在申请大的,这样线性化后就不会循环等待了

案例:

破坏占用且等待条件

  1. “同时申请”这个操作是一个临界区,我们用 Allocator这个类来管理这个临界区。它有两个重要功能:同时申请资源 apply() 和同时释放资源 free()。
  2. 账户 Account 类里面持有一个 Allocator 的单例(必须是单例,只能由一个人来分配资源)。当账户 Account 在执行转账操作的时候,首先向 Allocator 同时申请转出账户和转入账户这两个资源,成功后再锁定这两个资源;当转账操作执行完,释放锁之后,我们需通知 Allocator 同时释放转出账户和转入账户这两个资源。

破坏不可抢占条件

  1. 主动释放本线程占有的资源,这一点synchronized无法做到。
  2. 原因是 synchronized 申请资源的时候,如果申请不到,线程直接进入阻塞状态了,而线程进入阻塞状态,啥都干不了,也释放不了线程已经占有的资源。
  3. 不过在 SDK 层面还是解决了的,java.util.concurrent 这个包下面提供的 Lock 是可以轻松解决这个问题的。(提供tryLock(long, TimeUnit) 方法,在一段时间尝试获取锁。)

破坏循环等待条件

  1. 破坏这个条件,需要对资源进行排序,然后按序申请资源。我们假设每个账户都有不同的属性 id,这个 id 可以作为排序字段,申请的时候,我们可以按照从小到大的顺序来申请。比如对转出账户(this)和转入账户(target)排序,然后按照序号从小到大的顺序锁定账户。这样就不存在“循环”等待了。

标签:初阶,账户,编程,申请,死锁,线程,等待,资源
From: https://blog.csdn.net/weixin_39384775/article/details/139622680

相关文章

  • 【网络编程开发】17.“自动云同步“项目实践
    17."自动云同步"项目实践文章目录17."自动云同步"项目实践项目简介功能需求需求分析实现步骤1.实现TCP通信server.c服务端tcp.hclient.c客户端函数封装tcp.ctcp.hserver.cclient.c编译运行2.实现文件传输sever.cclient.ctcp.ctcp.hMakeifle编译运行3.实现用文件名......
  • 【完整解决方案】生产实战,数据库发生了死锁
    文章目录1.什么时候数据库会有死锁1.资源争用2.长时间持有锁3.并发事务4.不一致的锁定顺序示例Transaction1Transaction2避免死锁的方法2.发生死锁时自动死锁检测与解决手动处理实例3.如何查看数据库是否存在了死锁MySQLP......
  • 怎样解决 Bash 与其他编程语言交互时出现的兼容性问题?
    要解决Bash与其他编程语言交互时出现的兼容性问题,可以考虑以下几个方法:使用标准化的输入输出:确保你的Bash脚本与其他编程语言之间使用标准化的输入输出格式进行通信。这可以包括使用标准输入和标准输出进行交互,并使用标准格式(如JSON或CSV)来传递数据。使用跨平台的工具或......
  • 初阶 《函数》 4. 函数的调用
    4.函数的调用4.1传值调用函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参4.2传址调用传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操......
  • 初阶 《函数》 6. 函数的声明和定义
    6.函数的声明和定义6.1函数声明告诉编译器有一个函数叫什么、参数是什么、返回类型是什么。但是具体是不是存在,函数声明决定不了。函数的声明一般出现在函数的使用之前,要满足先声明后使用。函数的声明一般要放在头文件中intmain(void)//明确的说明,main函数不需要参......
  • 自学编程Java入门基础教学
    (首先下载typora/15天免费使用)MARKDOWN标题(符号必须英文输入法)标题#(#个数分级别)空格文案二级标题三级标题文字world!(前后两个*加粗)world!(1斜体*)world!(3*斜体加粗)world!(两个~波浪号删除线)引用吗喽小帆船自学Java寻大厂offer(>空格)分割线(三个-获三个*分割线)......
  • Java编程:动态规划
    背包问题:有一个背包,容量为4磅,现有如下物品要求达到的目标为装入的背包的总价值最大,并且重量不超出要求装入的物品不能重复动态规划算法介绍===================================================================动态规划(DynamicProgramming)算法的核心思想是......
  • 面向储存的源码级轻量预处理编程
    以下是对它的定义面向储存的源码级轻量预处理编程是一种在算法竞赛(competitiveprogramming)中常用技巧(skill),它是一种基于预处理的思想而演变出来的编程方法。要采用这种方法,首先可以把整个程序分为两部分:生成器(genernater)结果程序(result)我们通常使用生成器把一......
  • cjavapy编程书籍推荐
    cjavapy编程书店主要是收集了C/C++/C#、Java、Python等语言编程基础教程书籍,以及高级进阶教程书籍,还有其它编程相关的Linux、机器学习、编程提高及面试提高方面的书籍。1、cjavapy编程书店简介cjavapy编程书店主要收录编程相关的经典书籍,书籍的购买方式都是在抖音橱窗,书店只......
  • 好用的库函数,qsort函数大详解(干货满满!)(初阶)
    前言;  我一直在思考今天要写什么类型的文章,看到之前写的冒泡排序的写法,不过冒牌排序的算法只能针对于整型,我们如果想要排序浮点型,字符型的数据呢?这个时候我突然想到了比冒泡排序还好用的一个库函数,就是我们今天的主角——qsort函数,下面不多废话,直接进入正文: 目录:1.qsor......