并发——什么是线程死锁?如何避免死锁?

文章目录

  • 1. 认识线程死锁
  • 2. 如何避免线程死锁?

1. 认识线程死锁

线程死锁描述的是这样一种情况:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。

如下图所示,线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源,所以这两个线程就会互相等待而进入死锁状态。
在这里插入图片描述
下面通过一个例子来说明线程死锁,代码模拟了上图的死锁的情况 (代码来源于《并发编程之美》):

public class DeadLockDemo {private static Object resource1 = new Object();//资源 1private static Object resource2 = new Object();//资源 2public static void main(String[] args) {new Thread(() -> {synchronized (resource1) {System.out.println(Thread.currentThread() + "get resource1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread() + "waiting get resource2");synchronized (resource2) {System.out.println(Thread.currentThread() + "get resource2");}}}, "线程 1").start();new Thread(() -> {synchronized (resource2) {System.out.println(Thread.currentThread() + "get resource2");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread() + "waiting get resource1");synchronized (resource1) {System.out.println(Thread.currentThread() + "get resource1");}}}, "线程 2").start();}
}

Output

Thread[线程 1,5,main]get resource1
Thread[线程 2,5,main]get resource2
Thread[线程 1,5,main]waiting get resource2
Thread[线程 2,5,main]waiting get resource1

线程 A 通过 synchronized (resource1) 获得 resource1 的监视器锁,然后通过Thread.sleep(1000);让线程 A 休眠 1s 为的是让线程 B 得到执行然后获取到 resource2 的监视器锁。线程 A 和线程 B 休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁。上面的例子符合产生死锁的四个必要条件。

学过操作系统的朋友都知道产生死锁必须具备以下四个条件:

  1. 互斥条件:该资源任意一个时刻只由一个线程占用。
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件:线程已获得的资源在未使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。
  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

2. 如何避免线程死锁?

我上面说了产生死锁的四个必要条件,为了避免死锁,我们只要破坏产生死锁的四个条件中的其中一个就可以了。现在我们来挨个分析一下:

  1. 破坏互斥条件 :这个条件我们没有办法破坏,因为我们用锁本来就是想让他们互斥的(临界资源需要互斥访问)。
  2. 破坏请求与保持条件 :一次性申请所有的资源。
  3. 破坏不剥夺条件 :占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。
  4. 破坏循环等待条件 :靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。

我们对线程 2 的代码修改成下面这样就不会产生死锁了。

        new Thread(() -> {synchronized (resource1) {System.out.println(Thread.currentThread() + "get resource1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread() + "waiting get resource2");synchronized (resource2) {System.out.println(Thread.currentThread() + "get resource2");}}}, "线程 2").start();

Output

Thread[线程 1,5,main]get resource1
Thread[线程 1,5,main]waiting get resource2
Thread[线程 1,5,main]get resource2
Thread[线程 2,5,main]get resource1
Thread[线程 2,5,main]waiting get resource2
Thread[线程 2,5,main]get resource2Process finished with exit code 0

我们分析一下上面的代码为什么避免了死锁的发生?

线程 1 首先获得到 resource1 的监视器锁,这时候线程 2 就获取不到了。然后线程 1 再去获取 resource2 的监视器锁,可以获取到。然后线程 1 释放了对 resource1、resource2 的监视器锁的占用,线程 2 获取到就可以执行了。这样就破坏了破坏循环等待条件,因此避免了死锁。

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

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

相关文章

个人对智能家居平台选择的思考

本人之前开发过不少MicroPython程序,其中涉及到自动化以及局域网控制思路,也可以作为智能家居的实现方式。而NodeMCUESPHome的方案具有方便添加硬件、容易更新程序和容量占用小的优势,本人也查看过相关教程后感觉部署ESPHome和编译固件的步骤…

生成树协议

文章目录 STP冗余交换网络为什么存在广播风暴?广播的危害?交换环路的危害? 工作机制BPDU什么是最好的bpduBPDU触发机制 STP选举步骤配置协议分析字段分析开销模式端口状态 故障类型根桥故障直连故障间接故障 (链路中间可能有HUB&a…

# Linux下最好用的歌词工具:OSD Lyrics安装使用指引

Linux下最好用的歌词工具:OSD Lyrics安装使用指引 文章目录 Linux下最好用的歌词工具:OSD Lyrics安装使用指引1 安装1.1 直接安装1.2 源码安装 2 错误解决3 快捷方式与软件设置(很重要)4 首选项相关界面5 最后 OSD Lyrics 是一个桌…

人工智能、BIM技术、机器学习在智慧工地的应用

人工智能、BIM技术、机器学习在智慧工地的应用 智慧工地云平台是专为建筑施工领域所打造的一体化信息管理平台。通过大数据、云计算、人工智能、BIM、物联网和移动互联网等高科技技术手段,将施工区域各系统数据汇总,建立可视化数字工地。同时&#xff0…

第一百二十五天学习记录:C++提高:STL-deque容器(下)(黑马教学视频)

deque插入和删除 功能描述: 向deque容器中插入和删除数据 函数原型: 两端插入操作: push_back(elem); //在容器尾部添加一个数据 push_front(elem); //在容器头部插入一个数据 pop_back(); //删除容器最后一个数据 pop_front(); //删除容器…

MySQL安装和卸载

1.MySQL概述 MySQL概述 MySQL是一个[关系型数据库管理系统],由瑞典MySQL AB 公司开发,2008年被sun公司收购, 2009sun又被oracle收购,所以属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用…

自然语言处理学习笔记(三)————HanLP安装与使用

目录 1.HanLP安装 2.HanLP使用 (1)预下载 (2)测试 (3)命令行 (4)测试样例 3.pyhanlp可视化 4. HanLP词性表 1.HanLP安装 HanLP的 Python接口由 pyhanlp包提供,其安装…

halcon 学习笔记

图像的参数 图形参数 Iconic, 包括 image, region, XLD 1.1 image 图像由一个或者多个通道组成,是大小相同的矩阵,包含各种像素类型的灰度值 在图像显示界面,按ctrl健,可以查看当前的像素值 灰度图 一个通道像素点存放在一个矩…

HTML5 中新增了哪些表单元素?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ HTML5 中新增了的表单元素⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚…

权限校验—接口检验

一、背景介绍 最近项目中要实现根据不同用户去划分不同的角色,而不同角色具备调用不同接口的权限这个功能。用户在调用接口时需要校验用户是否具有权限访问接口,防止外界恶意调用随意篡改 二、思路&方案 为什么要进行接口鉴权? 接口鉴权…

基于VUE3+Layui从头搭建通用后台管理系统(前端篇)七:工作台界面实现

一、本章内容 本章实现工作台界面相关内容,包括echart框架引入,mock框架引入等,实现工作台界面框架搭建,数据加载。 1. 详细课程地址: 待发布 2. 源码下载地址: 待发布 二、界面预览 三、开发视频 基于VUE3+Layui从头搭建通用后台管理系统合集-工作台界面布局实现 五、…

FPGA----UltraScale+系列的PS侧与PL侧通过AXI-HP交互(全网唯一最详)附带AXI4协议校验IP使用方法

1、之前写过一篇关于ZYNQ系列通用的PS侧与PL侧通过AXI-HP通道的文档,下面是链接。 FPGA----ZCU106基于axi-hp通道的pl与ps数据交互(全网唯一最详)_zcu106调试_发光的沙子的博客-CSDN博客大家好,今天给大家带来的内容是&#xff0…

哪个版本的FL Studio更适合我?2023年到底应该入手哪一款FL Studio?

很多打算入手正版FL Studio的新手朋友都会纠结一个问题:哪个版本的FL Studio更适合我,2023年到底应该入手哪一款FL Studio?本文会介绍每个版本之间的差异点,并带大家选择适合自己的FL Sudio版本。 FL Studio Mac-安装包&#xff…

Spring系列三:基于注解配置bean

文章目录 💗通过注解配置bean🍝基本介绍🍝快速入门🍝注意事项和细节 💗自己实现Spring注解配置Bean机制🍝思路分析🍝注意事项和细节 💗自动装配 Autowired🍝案例1: Autow…

【算法篇C++实现】算法的时间、空间复杂度

文章目录 🚀一、算法的概念🚀二、算法的特征1.可行性2.确定性3.有穷性4.输入5.输出 🚀三、算法的评价1.正确性2.可读性3.健壮性 🚀四、算法的复杂度⛳(一)时间复杂度1、时间复杂度的概念2、大O的渐进表示法…

培训报名小程序报名功能完善

目录 1 修改数据源2 修改表单3 支付成功时修改状态4 创建报名成功页5 最终的效果总结 目前我们的报名功能已经搭建了一个基础版,后续需要展示用户已经报名的信息,需要添加一个状态来显示用户是否成功付费。 1 修改数据源 打开我们的报名数据源&#xff…

使用 Docker 和 Streamlit 构建和部署 LangChain 支持的聊天应用程序

文章目录 前言聊天应用程序组件和技术LangChain Python框架开放人工智能模型前端 Streamlit UI使用 Docker 进行部署Docker 优化以实现轻量级和快速构建Docker-compose.yaml 文件基础设施Streamlit 公共云谷歌应用引擎使用 Google Cloud Run 部署应用1.启动服务2. 创建角色并将…

HDFS中的Trash垃圾桶回收机制

Trash垃圾桶回收机制 文件系统垃圾桶背景功能概述Trash Checkpoint Trash功能开启关闭HDFS集群修改core-site.xml删除文件到trash删除文件跳过从trash中恢复文件清空trash 文件系统垃圾桶背景 回收站(垃圾桶)是windows操作系统里的一个系统文件夹&#…

Java版企业电子招标采购系统源码—企业战略布局下的采购寻源tbms

​ 项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以…

Jupyter Notebook 未授权访问远程命令执行漏洞

漏洞描述 Jupyter是一个开源的交互式计算环境,它支持多种编程语言,包括Python、R、Julia等。Jupyter的名称来源于三种编程语言的缩写:Ju(lia)、Py(thon)和R。 Jupyter的主要特点是它以笔记本(Notebook)的形式组织代码…