【javaEE初阶】第三节.多线程 (进阶篇 ) 死锁

news2025/1/23 21:11:48

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、"死锁"出现的典型场景
  • 二、产生 "死锁" 的必要条件
  • 三、解决 "死锁" 问题的办法

  • 总结


前言

今天对于多线程进阶的学习,今天我们今天来介绍有关死锁的内容;熟练的掌握死的出现场景;产生死锁的必要条件;解决死锁的方法等等;

死锁,是多线程中的一个比较典型的问题,是多线程代码中的常见 bug 

通俗的说,就是 在尝试加锁的时候,发现上次锁没有及时的释放(由于某些原因,或是是一些代码的 bug ),导致加锁没有加上 

于是,就会出现了 "死锁" 问题 ;


一、"死锁"出现的典型场景

(一)一个线程一把锁(可重入锁),若是不可重复锁,凉!

一个线程一把锁,这个就是之前所介绍的 可重入锁 ;

线程A 针对锁1 连续加锁两次,就构成了死锁 !!!

第一次加锁 加锁成功,第二次加锁 就需要第一次的锁释放,于是就阻塞等待;

但是,第一次加锁释放,就得依赖第二次加锁成功;

于是,"死锁" 就出现了!!!

(二)两个线程两把锁,相互获取对方锁,凉!

此时,不管是不是可重入锁,都会造成 "死锁" 问题 !!!

举例说明:

假设 甲同学 和 乙同学 居住在一起了 ;

甲同学 吃饺子喜欢蘸酱油,乙同学 吃饺子喜欢蘸醋,由于在一起了,生活习性都受到了彼此的影响,两位同学吃饺子的时候 喜欢都蘸上一点了 ;

有一天,吃饺子的时候,甲同学拿起了酱油,乙同学拿起了醋 ;

甲同学说:"你把醋给我,我用完了都给你";乙同学说:"你把酱油给我,我用完了就把醋给你" ;

此时,两者相持不下,这就造成了 "死锁" 问题 ;


此时,甲同学 和 乙同学 就可以看成是两个线程,酱油和醋 就可以看成是两把锁 ~

线程1 获取到锁A,线程2 获取到锁B;

线程1 尝试获取锁B(需要线程2 释放锁B) ,线程2 尝试获取到锁A(需要线程1 释放锁A);

在这种情况下,逻辑上就构成了循环,就构成了 "死锁" ;

(三)多个线程多个锁,"哲学家就餐问题",凉!!

此时,这种情况和 第二种情况 类似,只是更复杂一点而已 ~

在多个线程多把锁的情况下,"死锁"问题 就是一个概率性的问题,但是也绝对不能忽视 !!!

在谈到 "多个线程多把锁" 的时候,就会引出一个很经典的问题 —— "哲学家就餐问题"

故事背景:

有 5 个哲学家,相当于有 5 个线程,他们只会做两件事情:

思考人生(相当于是 线程休眠)
吃面条(相当于是 在CPU上运行)
由于多线程的调度是无序的,所以说 这几个哲学家 什么时候去思考人生,什么时候去吃面条,我们是不确定的 ;

同时,正常情况下,应该会有 5 双筷子;

但是,此时 在餐桌上 一共只有 5 根筷子,并且 这5 根筷子 分别在 两两哲学家 之间 ;

并且,他们之间都不相互嫌弃,吃面条的时候要拿起 左右手两双筷子(这就导致相邻的哲学家需要等待) 

此处的筷子就视为 两把"锁",只有这两把锁都获取到了,才可以吃面条 ;

出现 "死锁" 问题的情况:

假设 在同一时刻,所有的哲学家都想吃面条 

他们同时伸出左手,拿起左边的筷子;然后又同时伸出右手,尝试去拿右边的筷子;此时,右手的筷子都拿不起来,因此都无法吃面 ;

由于哲学家都非常固执,导致即使吃不到面条 也不会放下左手的筷子,这样的情况就会一直持续下去 ;

于是,这就构成了死锁 ;

 

二、产生 "死锁" 的必要条件 

鉴于 "死锁"问题,程序员大佬们 总结了 4 个 "死锁"产生的必要条件:

1.互斥使用(线程1 拿到锁A,其他线程就无法获取到 A)
2.不可抢占(线程1 拿到锁A,其他线程只能阻塞等待,等到线程1 主动释放锁,而不是强行把锁抢走)
3.请求和保持(当线程1 拿到锁A 之后,就会一直持有这个获取到锁的状态,直到说主动释放锁) 
4.循环等待(线程1 等待线程2,线程2 又尝试等待线程1)

 三、解决 "死锁" 问题的办法

根据 产生 "死锁" 的必要条件,我们可以知道,前三个必要条件 都是在描述锁的基本特点,在实际情况下 我们并不好直接去破坏 

但是,第四个必要条件 却是和代码编写密切相关 ;

如果我们能够在编码上做出一些注意和约定,就可以打破 "循环等待",避免死锁 !!!

打破 "循环等待" 的办法:
针对多把锁,进行编号:1、2、3、4、......

并且约定在获取多把锁的时候,要明确获取锁的顺序是 从小到大(或者 从大到小) 的顺序 ~

如(此处以从小到大为例):

线程要拿到 1、2 这两把锁,就先获取 1,再获取 2;

线程要拿到 2、4 这两把锁,就先获取 2,再获取 4 ~

只要所有的线程都遵循这个顺序,就不会出现 "循环等待",就不会出现死锁 !!! 

我们可以把这个解决办法 带入到上面的 "哲学家就餐问题" 看看

约定:获取所得顺序是:从小到大 ;

之后,最左边的哲学家 就可以得到两把锁了,于是就可以吃到面条了 ;

等到 吃完面条之后,会释放 4、5两把筷子;然后 最上面的哲学家 也可以吃到面条了,......,就这样的话,顺时针旋转,依次 5 位哲学家都可以吃上面条了 ;

谁最先吃到面条,谁最后吃到面条,一眼就可以看明白了 

于是,"循环等待"就被打破了,死锁问题就被解决了 ;

这种解决 "死锁"问题 的方法非常可靠,也非常的重要!!!


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MapGIS精品教程】007:MapGIS投影变换案例教程

MapGIS投影变换,包括创建坐标系、定义投影、单点投影、类投影、批量投影。 文章目录 一、创建坐标系1. 创建高斯平面坐标系2. 创建阿尔伯斯投影二、定义投影三、投影变换1. 单点投影2. 类投影3. 批量投影一、创建坐标系 在MagGIS数据库中,有个空间参考系的文件夹,内置了常见…

【tensorflow onnx】TensorFlow2导出ONNX及模型可视化教程

文章目录1 背景介绍2 实验环境3 tf2onnx工具介绍4 代码实操4.1 TensorFlow2与ONNX模型导出4.2 ONNX正确性验证4.3 TensorFlow2与ONNX的一致性检查4.4 多输入的情况4.5 设定输入/输出节点5 ONNX模型可视化6 ir_version和opset_version修改7 ONNX输入输出维度修改8 致谢原文来自于…

【教学典型案例】18.开门小例子理解面向对象

目录一:背景介绍业务场景:业务分析:二:实现思路1、面向过程:2、面向对象(抽象、封装、继承、多态)3、面向对象(抽象、封装、继承、多态、反射)三:实现过程1、…

如何在 Istio 中使用 SkyWalking 进行分布式追踪

在云原生应用中,一次请求往往需要经过一系列的 API 或后台服务处理才能完成,这些服务有些是并行的,有些是串行的,而且位于不同的平台或节点。那么如何确定一次调用的经过的服务路径和节点以帮助我们进行问题排查?这时候…

二极管损坏的原因有哪些?

大家好,我是记得诚。 最近项目上肖特基二极管出问题了,概率性损坏,二极管本来是一个很简单的器件,这次重新整理一下,供大家参考。 二极管损坏,个人总结有如下几种情况。 1、过压 在Ta=25℃下,超过二极管的最大反向电压VR,二极管可能会被击穿,导致损坏。 2、过流 …

SpringBoot的基本概念和使用

文章目录一、什么是SpringBoot二、Spring Boot优点三、Spring Boot项目创建四、Spring Boot 配置文件1. yml语法2.properties与yml关系3.多系统的配置五、Spring Boot日志文件1.日志对象2.日志级别日志级别的设置System.out.println VS 日志的两个致命缺点3.日志持久化4.更简单…

[ 常用工具篇 ] windows安装phpStudy_v8.1_X64

🍬 博主介绍 👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…

如何实现大文件断点续传、秒传

大家先来了解一下几个概念: 「文件分块」:将大文件拆分成小文件,将小文件上传\下载,最后再将小文件组装成大文件; 「断点续传」:在文件分块的基础上,将每个小文件采用单独的线程进行上传\下载&…

CobaltStrike密码爆破、伪造上线以及DDos——csIntruder

Git仓库: https://github.com/ljy1058318852/csIntruder0x01 概述 本项目包含CobaltStrike密码爆破、伪造上线以及DDos功能。其中伪造上线支持常见魔改版CS。 This project includes CobaltStrike password blasting, fake online and DDos functions. Among them…

云计算创新展望-精耕细作的超级云计算平台

前言在当今云计算深入各行业、计算量暴增现状之下,云计算生态迎来百花齐放。但用户不希望将所有鸡蛋放在一个篮子里面,因此每个企业都在发展自己的私有云、公有云等多云、混合云结构。因云计算的高灵活性、可扩展性、高性价比,在本地10台服务…

ubuntu的快速安装与配置

文章目录前言一、快速安装二 、基础配置1 Sudo免密码2 ubuntu20.04 pip更新源3 安装和配置oneapi(infort/mpi/mkl) apt下载第一次下载的要建立apt源apt下载(infort/mpi/mkl)4 安装一些依赖库等5 卸载WSLpython总结前言 win11系统 ubuntu20.04 提示:以下…

【力扣-10天SQL入门】5~8天刷题 知识点总结

https://leetcode.cn/study-plan/sql/?progressjgmzq5s第5天 合并175. 组合两个表就是一个简单的left join1581. 进店却未进行过交易的顾客Q:两个表Visits(有visit_id和customer_id两列)和Transactions(有transaction_id、visit_…

Go垃圾回收原理

术语介绍 赋值器:说白了就是你写的程序代码,在程序的执行过程中,可能会改变对象的引用关系,或者创建新的引用。 回收器:垃圾回收器的责任就是去干掉那些程序中不再被引用得对象。 STW:全称是stop the word,GC期间某个阶段会停止…

插值多项式的龙格现象的介绍与模拟

在文章拉格朗日插值多项式的原理介绍及其应用中,笔者介绍了如何使用拉格朗日插值多项式来拟合任意数据点集。   事实上,插值多项式会更倾向于某些形状。德国数学家卡尔龙格Carl Runge发现,插值多项式在差值区间的端点附近会发生扭动&#x…

一篇文章彻底理解setState是同步还是异步!

本文内容均针对于18.x以下版本setState 到底是同步还是异步?很多人可能都有这种经历,面试的时候面试官给了你一段代码,让你说出输出的内容,比如这样:constructor(props) {super(props);this.state {data: data} }comp…

Sentinel架构篇 - 来源访问控制

来源访问控制(黑白名单) 概念 Sentinel 提供了黑白名单限制资源能否通过的功能。如果配置了白名单,则只有位于白名单的请求来源的对应的请求才能通过;如果配置了黑名单,则位于黑名单的请求来源对应的请求不能通过。 …

图形报表ECharts

图形报表ECharts1 图形报表ECharts1.1 ECharts简介-富客户端图表库ECharts缩写来自Enterprise Charts,商业级数据图表,是百度的一个开源的使用JavaScript实现的数据可视化工具,可以流畅的运行在PC和移动设备上,兼容当前绝大部分浏…

【3.8】操作系统内存管理、Redis数据结构、哈希表

内存满了,会发生什么? 当应用程序读写了这块虚拟内存,CPU 就会去访问这个虚拟内存, 这时会发现这个虚拟内存没有映射到物理内存, CPU 就会产生缺页中断,进程会从用户态切换到内核态,并将缺页中…

MySQL索引15连问,抗住!

1. 索引是什么?索引是一种能提高数据库查询效率的数据结构。它可以比作一本字典的目录,可以帮你快速找到对应的记录。索引一般存储在磁盘的文件中,它是占用物理空间的。正所谓水能载舟,也能覆舟。适当的索引能提高查询效率&#x…

实战小项目之视频监控(1-2)

实战小项目之视频监控(1-2) Nginx 移植 前面也给大家提到了,我们可以使用 Nginx 来搭建 RTMP 流媒体服务器,譬如你可以在一台公网 IP 主 机上搭建流媒体服务器,当然,笔者并没有这个条件;这里我…