【多线程进阶】死锁问题

文章目录

  • 前言
  • 1. 什么是死锁
    • 1.1 死锁的三种典型情况
  • 2. 死锁产生的必要条件
  • 3.如何解决死锁问题
  • 总结


前言

上文锁策略中, 当谈到可重入锁和不可重入锁时, 我们引入了一个 “死锁” 的概念, 当针对一把不可重入锁进行连续两次的加锁行为时, 就会产生死锁.

本文就重点来讲解一下关于死锁的一些知识.

关注收藏, 开始学习吧🧐


1. 什么是死锁

在锁策略中, 我们提到过死锁这一概念, 死锁是这样一种情形: 多个线程同时被阻塞, 它们中的一个或者全部都在等待某个资源被释放. 由于线程被无限期地阻塞, 因此程序不可能正常终止.

1.1 死锁的三种典型情况

1. 一个线程, 一把不可重入锁. 该线程针对这个锁连续加锁两次, 就会出现死锁.
这就是我们上文提到的锁策略中的不可重入锁, 带来的死锁, 是因为针对一把不可重入锁, 连续加锁两次所导致的.

2. 两个线程, 两把锁. 这两个线程先分别获取到一把锁, 然后再同时尝试获取对方的锁.
这个场景其实可以通过生活场景来去理解, 就好比你把车钥匙落家里了, 但是家钥匙又落车里了. 如果你想开家门, 就得先开车门. 想开车门, 就得先开家门. 无限循环形成套娃.

3. 有N个线程, 有M把锁. 这几个线程互相获取锁, 也会有几率出现死锁
很经典的 “哲学家就餐问题” 就是用来描述这个情境的.

在这里插入图片描述

  • 有一张桌子, 围着一圈 哲学家, 桌子中间放着一盘意大利面. 每个哲学家两两之间, 放着一根筷子.
  • 每个哲学家主要做两件事, 思考人生或者吃面条. 思考人生时, 会放下筷子进行思考. 准备吃面时, 会拿起左手和右手的筷子开始吃面.
  • 每个哲学家, 什么时候思考, 什么时候吃面条, 都是随机的.
  • 每个哲学家一旦准备开始吃面条, 就会非常固执的要完成吃面条的操作, 即便是此时面前筷子被别人占用, 而且等待过程中也不会放下手里已经拿着的一根筷子(拿起一根时, 发现另外一根被别人占用), 开始阻塞等待.

基于以上的设定, 在大部分情况, 这些哲学家都可以很好地开展工作, 去思考, 去吃面条. 但是如果出现了极端情况, 就会发生死锁.

假设同一时刻, 五个哲学家同时拿起左手边的筷子, 然后再尝试拿右手的筷子, 就会
发现右手的筷子都被占用了. 由于哲学家们互不相让, 这个时候就形成了死锁.

在这里插入图片描述
在哲学家就餐问题中, 五个哲学家就相当于五个线程, 五根筷子就相当于五把锁.

2. 死锁产生的必要条件

在了解死锁出现的几个典型场景后, 请思考一下, 有什么办法能够解决死锁问题呢? 想知道如何解决死锁问题, 我们首先要从根本原因出发, 先明确发生死锁的原因, 明白死锁产生的必要条件是什么.

死锁产生的四个必要条件:

  • 互斥使用, 即当资源被一个线程使用 (占有) 时, 别的线程不能使用.
  • 不可抢占, 资源请求者不能强制从资源占有者手中夺取资源, 资源只能由资源占有者主动释放.
  • 请求和保持, 即当资源请求者在请求其他的资源的同时保持对原有资源的占有.
  • 循环等待, 即存在一个等待队列: P1占有P2的资源, P2占有P3的资源, P3占有P1的资源. 这样就形成了一个等待环路.

当上述四个条件都成立的时候, 便形成死锁. 四个条件缺一不可, 只要能够破坏其中的任意一个条件, 都可以避免出现死锁. 对于我们来说, 其中最容易破坏的就是 “循环等待”.

3.如何解决死锁问题

破坏 “循环等待” 是我们解决死锁问题的关键, 而如何具体的解决死锁问题, 实际的方法有很多, 学过操作系统的读者, 应该都听说过 “银行家算法”, 该算法其实就是用来解决死锁问题的, 不过对于我们来讲, 不够接地气.

在这里, 我们介绍一个, 更加简单, 也可以高效的解决死锁问题的方法 ---- 锁排序.

锁排序就是对锁来进行编号, 并且规定好加锁的顺序, 比如约定, 每个线程如果要获取多把锁, 必须先获取编号小的锁, 后获取编号大的锁. 只要所有线程加锁都严格遵守上述规则, 那么就不会出现 “循环等待” 的这种情况.

在上述哲学家就餐问题中, 我们只要约定好, 从一到五, 给每个筷子都设置一个编号, 所有哲学家, 拿筷子时先拿编号小的筷子, 再拿编号大的筷子, 这样就不会出现我们说的那种极端情况了.


总结

✨ 本文主要讲解了一些死锁的概念, 重点介绍了死锁的几种典型场景, 以及死锁产生的几个必要条件, 并且讲述了如何去解决死锁问题.
✨ 想了解更多的多线程知识, 可以收藏一下本人的多线程学习专栏, 里面会持续更新本人的学习记录, 跟随我一起不断学习.
✨ 感谢你们的耐心阅读, 博主本人也是一名学生, 也还有需要很多学习的东西. 写这篇文章是以本人所学内容为基础, 日后也会不断更新自己的学习记录, 我们一起努力进步, 变得优秀, 小小菜鸟, 也能有大大梦想, 关注我, 一起学习.

再次感谢你们的阅读, 你们的鼓励是我创作的最大动力!!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/148408.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【自动化测试】测试开发工具大合集

收集和整理各种测试工具,自动化测试工具,自动化测试框架,觉得有帮助记得三连一下。 欢迎提交各类测试工具到本博客。 通用测试框架 JUnit: 最著名的xUnit类的单元测试框架,但是不仅仅可以做单元测试。TestNG: 更强大的Java测试框…

深度学习(3)---PyTorch中的张量

文章目录 一、张量简介与创建1.1 简介1.2 张量的创建 二、张量的操作2.1 张量的拼接与切分2.2 张量索引 三、张量的数学运算 一、张量简介与创建 1.1 简介 1. 张量是一个多维数组,它是标量、向量、矩阵的高维拓展。 2. 在张量的定义中,方括号用于表示张…

基于j2ee的交通管理信息系统/交通管理系统

摘 要 随着当今社会的发展,时代的进步,各行各业也在发生着变化,比如交通管理这一方面,利用网络已经逐步进入人们的生活。传统的交通管理,都是工作人员线下手工统计,这种传统方式局限性比较大且花费较多。计…

Windows下Tensorflow docker python开发环境搭建

前置条件 windows10 更新到较新的版本,硬件支持Hyper-V。 参考:https://learn.microsoft.com/zh-cn/windows/wsl/install 启用WSL 在Powershell中输入如下指令: dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsys…

第十七章:Java连接数据库jdbc(java和myql数据库连接)

1.进入命令行:输入cmd,以管理员身份运行 windowsr 2.登录mysql 3.创建库和表 4.使用Java命令查询数据库操作 添加包 导入包的快捷键 选择第四个 找到包的位置 导入成功 创建java项目 二:连接数据库: 第一步:注册驱动…

【数据结构】抽象数据类型

🦄个人主页:修修修也 🎏所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 🎏数据类型 🎏抽象数据类型 结语 🎏数据类型 数据类型:是指一组性质相同的值的集合及定义在此集合上的一些操作的总称. 数据类型(d…

一文读懂UTF-8的编码规则

之前写过一篇文章“一文彻底搞懂计算机中文编码”里面只是介绍了GB2312编码知识,关于utf8没有涉及到,经过查询资料发现utf8是对unicode的一种可变长度字符编码,所以再记录一下。 现在国家对于信息技术中文编码字符集制定的标准是《GB 18030-…

什么是JWT?深入理解JWT从原理到应用

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《ELement》。🎯🎯 &#x1…

互联网Java工程师面试题·Dubbo篇·第一弹

目录 1、为什么要用 Dubbo? 2、Dubbo 的整体架构设计有哪些分层? 3、默认使用的是什么通信框架,还有别的选择吗? 4、服务调用是阻塞的吗? 5、一般使用什么注册中心?还有别的选择吗? 6、默认使用什么序列化框架&…

SoloX:Android和iOS性能数据的实时采集工具

SoloX:Android和iOS性能数据的实时采集工具 github地址:https://github.com/smart-test-ti/SoloX 最新版本:V2.7.6 一、SoloX简介 SoloX是开源的Android/iOS性能数据的实时采集工具,目前主要功能特点: 无需ROOT/越狱…

美团外卖优惠券小程序 美团优惠券微信小程序 自带流量主模式 带教程

小程序带举牌小人带菜谱流量主模式,挺多外卖小程序的,但是都没有搭建教程 搭建: 1、下载源码,去微信公众平台注册自己的账号 2、解压到桌面 3、打开微信开发者工具添加小程序-把解压的源码添加进去-appid改成自己小程序的 4、…

蓝桥等考Python组别九级007

第一部分:选择题 1、Python L9 (15分) 运行下面程序,可以输出几行“*”?( ) for i in range(0, 3): for j in range(0, 5): print(*, end ) print() 2345 正确答案:B 2、P…

交叉编译和GCC编译器

目录 交叉编译 hello.c文件 提问 GCC编译器 GCC编译过程 GCC常用选项 编译多个文件 预处理 编译 汇编 链接 交叉编译 hello.c文件 #include <stdio.h>int main(int argc, char argv) {if(argc > 2)printf("Hello, %s!\n", argv[1]);elseprintf…

Java基于SSM的校园一卡通系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

540. 有序数组中的单一元素

链接&#xff1a; 540. 有序数组中的单一元素 代码&#xff1a; 方法一&#xff1a;全数组的二分查找 思路和算法 假设只出现一次的元素位于下标 xxx&#xff0c;由于其余每个元素都出现两次&#xff0c;因此下标 xxx 的左边和右边都有偶数个元素&#xff0c;数组的长度是奇…

《C和指针》笔记31:多维数组的数组名、指向多维数组的指针、作为函数参数的多维数组

文章目录 1. 指向多维数组的数组名2. 指向多维数组的指针3. 作为函数参数的多维数组 1. 指向多维数组的数组名 我们知道一维数组名的值是一个指针常量&#xff0c;它的类型是“指向元素类型的指针”&#xff0c;它指向数组的第1个元素。那么多维数组的数组名代表什么呢&#x…

桥梁模板人工费多少钱?

桥梁模板是桥梁工程中不可或缺的一部分&#xff0c;它起到支撑和固定混凝土浇筑的作用。在桥梁建设中&#xff0c;模板人工费用是一个重要的成本因素。那么&#xff0c;桥梁模板人工费到底是多少呢&#xff1f;下面我们来详细了解一下。 首先&#xff0c;需要明确的是&#xff…

全栈开发笔记2:项目部署上线的三种方式

文章目录 最原始的方式宝塔Docker 部署其他 本文为编程导航实战项目学习笔记。 项目部署的三种方式&#xff1a; 最原始方式✅ yum 手动安装 jdk mysql tomcat nginx打包前端项目&#xff0c;放到某个目录&#xff0c;修改 nginx 配置修改线上的 mysql 配置&#xff0c;打包 j…

数据集笔记:OpenCelliD(手机基站开放数据库)

下载数据的方式可见&#xff1a;【数据获取】全球最大手机基站开源数据库 1 读取数据 import pandas as pdpd.read_csv(C:/Users/16000/Downloads/454.csv/454.csv,headerNone,names[radio,mcc,net,area,cell,unit,lon,lat,range,samples,changeable1,created1,updated,AveSi…

【易语言】m3u8下载器源码

前阵子接了个下载视频的小单子&#xff0c;部分视频是m3u8链接的&#xff0c;临时弄了个批量下载器&#xff0c;如图&#xff1a; 这东西网上虽然很多&#xff0c;但还是喜欢自己折腾一下&#xff0c;就直接开源了。代码好不好&#xff0c;只看能不能跑。 原理就是调用ffmpeg&a…