当前位置: 首页 > news >正文

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

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

文章目录

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

  • 总结


前言

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

死锁,是多线程中的一个比较典型的问题,是多线程代码中的常见 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提供了大量能使我们快速便捷地处理数据的函数和方法。

相关文章:

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

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、"死锁"出现的典型场景二、产生 "死锁" 的必要条件 三、解决 "死锁" 问题的办法 总结前言 今天对于多线程进阶的学习&#…...

基于密集连接的轻量级卷积神经网络,用于使用边云架构的露天煤矿服务识别

遥感是快速检测非法采矿行为的重要技术工具。由于露天煤矿的复杂性,目前关于露天煤矿自动开采的研究较少。基于卷积神经网络和Dense Block,我们提出了一种用于从Sentinel-2遥感图像中提取露天煤矿区域的轻量级密集连接网络-AD-Net,并构建了三…...

无刷高速风筒方案介绍--【PCBA方案】

疫情三年过去,春节后,一个新的开始,大家满怀希望畅谈今年好气象。 三年来一波一波的封城、隔离、核酸,经济压抑到了无以复加的地步,也导致了诸多社会问题的出现。消费力被磨平,人们小心翼翼的生活。 常跟…...

花括号展开II[栈模拟dfs]

栈模拟dfs前言一、花括号展开II二、栈模拟dfs总结参考资料前言 递归调用,代码非常的简洁。但是可以通过显式栈来模拟栈中的内容,锻炼自己的代码能力,清楚知道栈帧中需要的内容。 一、花括号展开II 二、栈模拟dfs 每碰到一个左括号&#xf…...

神经网络分类任务(手写数字识别)

1.Mnist分类任务 网络基本构建与训练方法,常用函数解析 torch.nn.functional模块 nn.Module模块 学习方法:边用边查,多打印,duogua 使用jupyter的优点,可以打印出每一个步骤。 2.读取数据集 自动下载 %matplotl…...

FCN网络(Fully Convolutional Networks)

首个端到端的针对像素级预测的全卷积网络 原理:将图片进行多次卷积下采样得到chanel为21的特征层,再经过上采样得到和原图一样大的图片,最后经过softmax得到类别概率值 将全连接层全部变成卷积层:通常的图像分类网络最后几层是全…...

随想录二刷Day15——二叉树

文章目录二叉树2. 递归遍历二叉树3. 二叉树的迭代遍历4. 二叉树的统一迭代法二叉树 2. 递归遍历二叉树 144. 二叉树的前序遍历 class Solution { public:vector<int> preorderTraversal(TreeNode* root) {vector<int> result;preorder(root, result);return res…...

docker-compose部署kafka服务时如何同时允许内外网访问?

背景 最近在学习kafka相关知识&#xff0c;需要搭建自己的kafka环境。综合考虑后决定使用docker-compose来管理维护这个环境。 docker-compose.yml Bitnami的yml文件就很不错&#xff0c;这里直接拿来用了。 version: "2"services:zookeeper:image: docker.io/bi…...

数据结构刷题(二十):17电话号码的字母组合、39组合总和、40组合总和II

一、电话号码的字母组合题目链接思路&#xff1a;回溯三部曲。确定回溯函数参数&#xff1a;题目中给的 digits&#xff0c;还要有一个参数就是int型的index&#xff08;记录遍历第几个数字&#xff0c;就是用来遍历digits的&#xff0c;同时也代表了递归的深度&#xff09;&am…...

Java面试总结(五)

sleep() 方法和 wait() 方法对比 相同点 两者都可以暂停线程的执行&#xff1b;两者都可以响应中断。 不同点 sleep()方法不会释放锁&#xff0c;wait()方法会释放锁&#xff1b; sleep()方法主要用于暂停线程的执行&#xff0c;wait()方法主要用于线程之间的交互/通信&…...

三维人脸实践:基于Face3D的渲染、生成与重构 <二>

face3d: Python tools for processing 3D face git code: https://github.com/yfeng95/face3d paper list: PaperWithCode 3DMM方法&#xff0c;基于平均人脸模型&#xff0c;可广泛用于基于关键点的人脸生成、位姿检测以及渲染等&#xff0c;能够快速实现人脸建模与渲染。推…...

在linux上部署Java项目

在Linux部署Java环境 要是想要部署java web程序,首先要配置环境 jdk tomcat mysql 安装jdk 推荐的方法是使用yum直接安装openjdk(开源的,与官方的jdk功能差不多),目前使用的最多的就是jdk8系列 yum list | grep jdk 在源上搜索所有关于jdk的文件 devel表示development的意思…...

线性表的接口

线性表的实现方式 顺序表 顺序表是一种线性表的实现方式&#xff0c;它是用一组地址连续的存储单元依次存储线性表中的数据元素&#xff0c;使得逻辑上相邻的元素在物理上也相邻⁴。顺序表可以用数组来实现&#xff0c;它的优点是可以快速定位第几个元素&#xff0c;但是缺点…...

spark三种操作模式的不同点分析

通常情况下,由于mapreduce计算引擎的效率问题,大部分公司使用的基本都是hive数仓spark计算引擎的方式搭建集群,所以对于spark的三种操作方式来进行简单的分析。在日常开发中&#xff0c;使用最多的方式取决于具体的需求和场景。以下是每种方式的一些常见用途&#xff1a;Spark …...

Vue3做出B站【bilibili】 Vue3+TypeScript【快速入门一篇文章精通系列(一)前端项目案例】

本项目分为二部分 1、后台管理系统&#xff08;用户管理&#xff0c;角色管理&#xff0c;视频管理等&#xff09; 2、客户端&#xff08;登录注册、发布视频&#xff09; Vue3做出B站【bilibili】 Vue3TypeScript【快速入门一篇文章精通系列&#xff08;一&#xff09;前端项目…...

猜数游戏--课后程序(Python程序开发案例教程-黑马程序员编著-第3章-课后作业)

实例10&#xff1a;猜数游戏 猜数游戏是一个古老的密码破译类、益智类小游戏&#xff0c;通常由两个人参与&#xff0c;一个人设置一个数字&#xff0c;一个人猜数字&#xff0c;当猜数字的人说出一个数字&#xff0c;由出数字的人告知是否猜中&#xff1a;若猜测的数字大于设…...

Nvidia jetson nano 部署yolov5_技术文档

Nvidia jetson nano 部署yolov5_技术文档 每天一句小姜格言&#xff1a;我行&#xff0c;我不是一般人儿 部署开始&#xff1a; 1、通过FileZilla&#xff0c;将window文件传输至jetson nano 上的nano文件夹下。 2、查看cuda 我买的jetson nano是带有配置好的镜像。系统配置…...

获取当前天数前N天

获取当前天数前N天 先封装到js里面 export const isTime (val) > {// 1.获取当前时间年月日时分秒格式xxxx-xx-xx xx:xx:xxvar myDate new Date() // 当前时间var y myDate.getFullYear() // 当前年份四位数var m myDate.getMonth() 1 < 10? 0 (myDate.getMont…...

Linux---基本指令

专栏&#xff1a;Linux 个人主页&#xff1a;HaiFan. 基本指令ls 指令pwd命令cd 指令touch指令mkdir指令&#xff08;重要&#xff09;rmdir指令 && rm 指令&#xff08;重要&#xff09;man指令&#xff08;重要&#xff09;cp指令&#xff08;重要&#xff09;mv指令…...

【UE4 RTS游戏】02-摄像机运动_完成摄像机在X轴上运动的相关步骤

效果通过控制键盘WS键使得“CameraPawn”进行前后移动步骤将landscape的Z轴位置更改为0删除“PostProcessVolume”将“LightmassImportanceVolume”移入Lighting文件夹内新建一个蓝图类&#xff0c;父类是Pawn&#xff0c;命名为“CameraPawn”将“MyController”重命名为“Cam…...

Kubernetes学习(五)持久化存储

Volume 卷 容器中的文件在磁盘上是临时存放的&#xff0c;这给容器中运行的特殊应用带来了一些问题。首先&#xff0c;当容器崩溃时&#xff0c;kubectl将重新启动容器&#xff0c;容器中的文件将会丢失--应为容器会以干净的状态重建。其次&#xff0c;当在一个Pod中运行多个容…...

下一个7年,保持期待、持续思考,酷雷曼继续向前!

过去7年&#xff0c;我们一直在思考&#xff0c; VR技术究竟能为我们的生活带来什么&#xff1f; 是足不出户就能云游千里的秀美风光&#xff1f; 是在家就能沉浸式体验线上消费的便利&#xff1f; 还是为商企和用户搭建更快速的沟通桥梁&#xff1f; NO.1、技术变革 在信…...

天梯赛训练L1-010--L1-012

目录 1、L1-010 比较大小 2、L1-011 A-B 3、L1-012 计算指数 4&#xff0c;一些题外话 1、L1-010 比较大小 分数 10 本题要求将输入的任意3个整数从小到大输出。 输入格式&#xff1a; 输入在一行中给出3个整数&#xff0c;其间以空格分隔。 输出格式&#xff1a; 在一…...

三分钟完成Stable Diffusion本地安装(零基础体验AI绘画)

三分钟完成Stable Diffusion本地安装前言安装步骤下载链接前言 最近AI绘画很火&#xff0c;很多无编程基础的小伙伴也想体验一下&#xff0c;所以写这篇博客来帮助小伙伴们愉快的体验一下~废话少说&#xff0c;我们直接开整&#xff01; 安装步骤 首先&#xff0c;下载本项目的…...

电子台账:教程目录及软件下载

前面内容有点杂乱&#xff0c;这里整理一下教程目录。重点是制作模板&#xff0c;企业只要学会适合自己的一种就行。如果这些模板都学会做了&#xff0c;那可以当老师了。1 目录1 模板制作之一——列过滤&#xff08;水平过滤&#xff09;2 模板制作之二——行过滤&#xff08;…...

多态的优势和弊端

目录 1.多态的优势 2.多态的弊端是什么&#xff1f; 3.引用数据类型的类型&#xff0c;转换有几种方式 4.强制类型转换能解决什么问题楠&#xff1f; 1.多态的优势 方法中&#xff0c;使用父类作为参数&#xff0c;可以接收所有子类的对象 package ploydemo3;import java.u…...

android h5考勤管理系统myeclipse开发mysql数据库编程服务端java计算机程序设计

一、源码特点 android h5考勤管理系统是一套完善的WEBandroid设计系统&#xff0c;对理解JSP java&#xff0c;安卓app编程开发语言有帮助&#xff08;系统采用web服务端APP端 综合模式进行设计开发&#xff09;&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主…...

第二道pwn题:shellcode

题目来自视频&#xff1a;链接&#xff1a;https://pan.baidu.com/s/17vX9dbfHkXBw71mcEXBgNQ?pwd6666 提取码&#xff1a;6666查看文件类型和保护&#xff0c;虽然现在的我还没有明白太多的保护。64位&#xff0c;放到ida里边rbp:保存的是栈中当前执行函数的基本地址。当前执…...

《华为数据之道》读书笔记

《华为数据之道》读书笔记第二章&#xff1a;2.2.1 管理总纲有四点&#xff1a;信息架构管理原则、数据产生管理、数据应用管理原则、数据问责与奖惩管理原则2.1.2 信息架构管理政策&#xff1a;管理信息架构的角色与职责&#xff1a;公司数据Owner、各数据Owner、数据管理专业…...

C++源码pcl1.13.0库编译环境搭建及配置

Pcl github库https://github.com/PointCloudLibrary/pcl官网地址https://pointclouds.org/Pcl exe的下载地址&#xff0c;各个版本&#xff0c;以及各版本对应的源码https://github.com/PointCloudLibrary/pcl/releases源码需要编译&#xff0c;编译之前安装AllInOne的exe程序&…...