手画图解 | 关于死锁,面试的一切都在这里了

news2024/11/25 6:40:07

什么是死锁(Deadlock)

死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象。若无外力作用,它们都将无法推进下去。

产生死锁的四个必要条件得烂熟于心:

  • 互斥条件:进程要求对所分配的资源进行排他性控制,即在一段时间内某资源仅为一个进程所占用。此时若有其他进程请求该资源,则请求进程只能等待。

  • 不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放。

  • 请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。

  • 循环等待条件:存在一种进程资源的循环等待链,连中每一个进程已获得的资源同时被链中下一个进程所请求。

相应的,如果想在程序运行之前预防发生死锁(也成为 “死锁预防”),必须设法破坏产生死锁的四个必要条件之一

  • 破坏互斥条件:允许系统资源都能共享使用,则系统不会进行死锁状态。这种方案并不太可行,因为有些资源根本就不能同时访问,比如打印机。

  • 破坏不剥夺条件:当一个已经保持了某些不可剥夺资源的进程,请求新的资源时得不到满足,它必须释放已经保持的所有资源,待以后需要时再重新申请。这种方法常用于状态易于保存和恢复的资源,如 CPU 的寄存器及内存资源,一般不能用于打印机之类的资源。

  • 破坏请求和保持条件:采用预先静态分配方法,即进程在运行前一次申请完他所需要的全部资源,在他的资源未满足前,不把它投入运行。一旦运行后,这些资源就一直归它所有,也不再提出其他资源请求,这样就可以保证系统不会发生死锁。

  • 破坏循环等待条件:采用顺序资源分配法。首先给系统中的资源编号,规定每个进程,必须按编号递增的顺序请求资源,同类资源一次申请完。也就是说,只要进程提出申请分配资源,则该进程在以后的资源申请中,只能申请编号比之前大的资源。

光看罗列出来的几点文字肯定还是不能完全理解,下面会结合实例来给大伙解释。

用 Java 写一个死锁

这绝对是面试中 Java 手写题的 TOP2!!!除了人尽皆知的手写单例模式,手写死锁可能有些小伙伴会遗漏掉。

逻辑其实非常简单,我们申请两个资源,开两个线程,每个线程持有其中的一个资源,并且互相请求对方的资源,就构成了死锁。

MySQL 死锁

MySQL 经典的死锁案例

下面来看个 MySQL 经典的死锁案例:转账

A 账户给 B 账户转账 50 元的同时,B 账户也给 A 账户转账 30 元

正常情况下,如果只有一个操作,A 给 B 转账 50 元,可以在一个事务内完成,先获取 A 用户的余额和 B 用户的余额,因为之后需要修改这两条数据,所以需要通过写锁(for UPDATE)锁住他们,防止其他事务更改导致我们的更改丢失而引起脏数据

但如果 A 给 B 转账和 B 给 A 转账同时发生,那就是两个事务,可能发生死锁:

1)A 用户给 B 用户转账 50 元,需在程序中开启事务 1 来执行 SQL,获取 A 的余额同时锁住 A 这条数据。

2)B 用户给 A 用户转账 30 元,需在程序中开启事务 2 来执行 SQL,并获取 B 的余额同时锁住 B 这条数据。

3)在事务 1 中执行剩下的 SQL,此时事务 1 是获取不到 B 的锁的,也即 select for update 就会被阻塞住;

4)同理,事务 2 继续执行剩下的 SQL,请求 A 的锁,也是获取不到的

事务 1 和事务 2 存在相互等待获取锁的过程,导致两个事务都挂起阻塞,最终抛出获取锁超时的异常。

如何解决 MySQL 死锁

要想解决上述死锁问题,我们可以从死锁的四个必要条件入手。

指导思想其实很明确:就是保证 A 向 B 转账和 B 向 A 转账这两个事务同一时刻只能有一个事务能成功获取到锁

由于互斥和不剥夺是锁本质的功能体现,无法修改,所以咱们从另外两个条件尝试去解决。

1)破坏 “请求和保持” 条件:A 和 B 之间的操作用同一个锁锁住(比如用 Redis 分布式锁做,A 和 B 之间的锁的 key 表示为 A:B,可以让 id 小的用户排在前面,id 大的用户排在后面,这样来设计 key。如果存在分库分表的情况,用 hashcode 来做比较也行),保证 A 向 B 转账和 B 向 A 转账这两个事务同一时刻只能有一个事务能成功获取锁

2)破坏 “循环等待” 条件:先获取更小的锁,获取到了小的锁才能获取大锁(所谓小锁还是大锁,也可以简单的根据用户的 id 来进行区分,先请求用户 id 较小的,再请求用户 id 较大的)。比如 A.id < B.id,那么 A 和 B 之间的操作,都是要先获取 A 锁,再获取 B 锁

具体代码可参考如下:

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

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

相关文章

艾美捷QuickTiter 逆转录病毒定量试剂盒测定原理

逆转录病毒基因转移是一种有效地将稳定的、可遗传的遗传物质导入大肠杆菌的技术任何分裂细胞类型的基因组。不能复制的逆转录病毒通常通过将逆转录病毒载体转染到包装细胞系中。逆转录病毒根据用于进入宿主细胞的受体。亲嗜性病毒可以识别仅在小鼠身上发现的受体和大鼠细胞。兼…

【信息融合】基于matlab BP神经网络和DS证据理论不确定性信息融合问题【含Matlab源码 2204期】

⛄一、 D-S证据理论及解释 证据理论由Dempster在1967年最初提出,并由他的学生Shafer改进推广使之成为符合有限离散领域中推理的形式,因此称为D-S理论。证据理论讨论一个“辨识框架”(Frame of Discernment)Θ,它是关于命题的相互独立的可能答案或假设的一个有限集合。按传统方…

Qml中的那些坑(三)---MouseArea上的ListView滚轮事件穿透

【写在前面】 最近在 Qml 中使用 MouseArea 时发现了一个奇怪的现象&#xff1a; 位于 MouseArea 上的 ListView 在处理了滚轮事件的情况下进行滚轮&#xff0c;下面的 MouseArea 却在某些情况下接收到了这个事件。 按照直觉&#xff0c;ListView 明明有内部的滚轮事件处理&…

Cesium中的DataSource和Entity关系

本章主要探讨一下Cesium中的DataSource和Entity。 介绍 首先简单说一下Entity与Primitive。 Cesium为开发者提供了丰富的图形绘制和空间数据管理的API&#xff0c;可以分为两类&#xff0c;一类是面向图形开发人员的低层次API&#xff0c;通常被称为Primitive API&#xff0…

Java基础知识点整理

一、Java概述 1、何为编程 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码&#xff0c;并最终得到结果的过程。 为了使计算机能够理解人的意图&#xff0c;人类就必须要将需解决的问题的思路、方法、和手段通过计算机能够理解的形式告诉计算机&#xff…

助力工业物联网,工业大数据项目介绍及环境构建【一】

文章目录工业大数据项目介绍及环境构建01&#xff1a;专栏目标02&#xff1a;项目背景03&#xff1a;项目需求04&#xff1a;业务流程05&#xff1a;技术选型06&#xff1a;Docker的介绍07&#xff1a;Docker的网络08&#xff1a;Docker的使用09&#xff1a;Oracle的介绍10&…

关于SQL的返回行数top

第一节.知识点三:关键字wlth tles 我要讲的是关于SQL的3个限制返回行数top: 1.使用具有恒定值的top&#xff1b; 2.关键字percent(%)返回行的百分比&#xff1b; 3.理解关键字wlth tles 上一次已经讲了前两个了&#xff0c;现在我要讲的是第三个 3.理解关键字wlth t…

【计算机毕业设计】69.助残志愿者系统源码

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 本课题要求实现一套助残助残志愿者系统设计与开发&#xff0c;系统主要包括系统用户信息、志愿者信息、服务项目、志愿项目&#xff0c;志愿者培训、志愿项目、公益活动等功能模块。 基于上述分析&#xff0…

助力教育信创快速发展,统信软件与山东四所高校建立信创应用重点实验室

国家在“十三五”、“十四五”规划中重点强调了信息安全在国家战略中的重要地位&#xff0c;而大力发展教育信创有助于我国信息安全的快速落地。同时&#xff0c;教育部等六部门印发《关于推进教育新型基础设施建设构建高质量教育支撑体系的指导意见》也提到&#xff1a;推广可…

E+H浊度仪维修CUE22-A1A浊度分析仪维修概述

CUE21/22浊度仪参数如下&#xff1a; 测量参数&#xff1a;浊度 测量原理&#xff1a;散射光原理 应用场合&#xff1a;饮用水&#xff1b;生产用水 处理后的过程水 测量范围&#xff1a;0…100NTU&#xff1b;0…1000NTU 信号输出&#xff1a;4 ... 20 mA 通讯协议&…

多线程同步,信号,生产者消费者模型

目录1.线程互斥它是对的吗&#xff1f;合理吗&#xff1f;(任何场景)2.怎么解决饥饿问题&#xff1f;3.条件编译1.生产者和消费者模型2.编写代码实现一个基于堵塞队列的生产者消费者模型4.POSIX信号量5.环形队列1.线程互斥它是对的吗&#xff1f;合理吗&#xff1f;(任何场景) …

【JavaSE】多态

目录 1、多态 1.1、多态的概念 1.2、多态的实现条件 1.3、向上转型和向下转型 1.3.1、向上转型 1.3.2、向下转型 1.3.3、instanceof关键字 2、重写 2.1、重写的使用 2.2、动态绑定和静态绑定 2.2.1、动态绑定 2.2.2、静态绑定 2.3、再谈重写 3、多态的优缺点 4、…

LabVIEW浮点型和双精度数据类型之间的精度差异是什么 为什么 在LabVIEW 中, 浮点 数 会 失去 精度?

LabVIEW浮点型和双精度数据类型之间的精度差异是什么 为什么 在LabVIEW 中&#xff0c; 浮点 数 会 失去 精度&#xff1f; 程序中使用浮点数据类型或双精度数据类型。这些数据类型之间有什么区别&#xff1f; 浮点型的变量只有 7 位精度&#xff0c;而双精度类型的变量有 15…

算法竞赛入门【码蹄集进阶塔335题】(MT2296-2300)

算法竞赛入门【码蹄集进阶塔335题】(MT2296-2300&#xff09; 文章目录算法竞赛入门【码蹄集进阶塔335题】(MT2296-2300&#xff09;前言为什么突然想学算法了&#xff1f;为什么选择码蹄集作为刷题软件&#xff1f;目录1. MT2296 找朋友2. MT2297 盒子与球3. MT2298 点餐4. MT…

第二章Java概述

第二章Java概述 2.1 Java技术体系平台 Java SE:标准版 Java EE:企业版 Java ME&#xff1a;小型版 2.2Java重要特点&#xff08;四个&#xff09; 1&#xff09;java语言是面向对象的&#xff08;oop&#xff09; 2)java语言是健壮的。java的强类型机制、异常处理、垃圾的自动…

Kamiya丨Kamiya艾美捷人CP ELISA说明书

Kamiya艾美捷人CP ELISA预期用途&#xff1a; 人CP ELISA是一种高灵敏度的双位点酶联免疫分析&#xff08;ELISA&#xff09;人体生物样品中CP的测定。仅供研究使用。不用于诊断程序。 引言 铜蓝蛋白是参与铜转运的多功能蛋白&#xff0c;也是重要的血清抗氧化剂。在此期间炎…

【Canvas】js用Canvas绘制漩涡螺旋图动画效果

学习JavaScript编程&#xff0c;会用Canvas画图吗&#xff0c;学会它&#xff0c;能画很多有趣的事物&#xff0c;可自由发挥想象&#xff0c;会发现图形学的美&#xff0c;收获很多&#xff0c;这里有一个例子&#xff0c;如何用canvas画漩涡螺旋图动图效果&#xff0c;接下来…

c语言tips-结构体

1. 结构体定义和使用 #include <stdio.h>struct stu {int age;int height;int weight; };int main(int argc, char *argv[]) {struct stu stu1;stu1.age 18;stu1.height 172;stu1.weight 62;printf("年龄为&#xff1a;%d, 身高为&#xff1a;%d, 体重为&#x…

Self-attention自注意力机制——李宏毅机器学习笔记

self-attention想要解决的问题 复杂的输入 每次输入的length不同时&#xff0c;即Vector Set大小不同&#xff0c;该如何处理&#xff1f; one-hot encoding&#xff0c;缺点&#xff1a;所有的词汇之间没有语义资讯。 word embedding&#xff0c;会给每一个词汇一个向量&…

02-Docker-常用命令

目录 一、帮助启动类命令 启动docker 停止docker 重启docker 查看docker状态 开机启动 查看docker概要信息 查看docker总体帮助文档 查看docker命令帮助文档 二、镜像命令 1. 列出本地主机上的镜像 2. 查找镜像 3. 下载镜像 4. 查看镜像/容器/数据卷所占的空间 5.…