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

死锁是什么?死锁是如何产生的?如何破除死锁?

1. 死锁是什么

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

2. 死锁的三种典型情况

  1. 一个线程, 一把锁, 是不可重入锁, 该线程针对这个锁连续加锁两次, 就会出现死锁.

  2. 两个线程, 两把锁, 让两个线程先分别获取到一把锁, 然后再同时尝试获取对方的锁.

    • 假如A和B去吃饺子, A先拿起了酱油碟, B先拿起了醋碟. 此时A说’你先把醋给我, 我用完了就把酱油给你’, B说’你先把酱油给我, 用完了再把醋给你’
    • 如果两个人互不相让, 就产生了死锁.
    • 酱油和醋相当于是两把锁, 这两个人就是两个线程.
  3. N个线程M把锁

    • “哲学家就餐问题”

    • 有个桌子, 围着一圈哲学家, 桌子中间放着一盘意大利面. 每个哲学家两两之间, 放着一根筷子.

      在这里插入图片描述

    • 每个哲学家只做两件事: 思考人生 或者 吃面条. 思考人生的时候就会放下筷子. 吃面条就会拿起左右两边的筷子(先拿起左边, 再拿起右边).

      在这里插入图片描述

    • 如果哲学家发现筷子拿不起来了(被别人占用了), 就会阻塞等待.

      在这里插入图片描述

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

      在这里插入图片描述

3. 死锁产生的必要条件

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

  • 互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用

  • 不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。

  • 请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。一个线程去尝试获取多把锁, 在获取第二八所的过程中, 保持对第一把锁的获取状态.

  • 循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路

当上述四个条件都成立的时候,便形成死锁。当然,死锁的情况下如果打破上述任何一个条件,便可让死锁消失。

最容易破坏的就是 “循环等待”.

4. 如何解决死锁

破坏循环等待

最常用的一种死锁阻止技术就是锁排序. 假设有 N 个线程尝试获取 M 把锁, 就可以针对 M 把锁进行编号(1, 2, 3…M).

N 个线程尝试获取锁的时候, 都按照固定的按编号由小到大顺序来获取锁. 这样就可以避免环路等待.

还是上述的哲学家就餐问题. 2号人拿起1号筷子, 3号人拿起2号筷子…

在这里插入图片描述

到了1号人, 按照编号由小到大顺序来获取锁, 他应该拿起1号筷子, 但是当前1号筷子被占用了, 那么1号人就陷入了阻塞状态

在这里插入图片描述

这样5号人就可以拿起4, 5两根筷子, 当他吃完, 4号筷子被释放; 4号人也可以使用3, 4两根筷子, 然后释放…直到2号人释放了1, 2两个筷子, 1号人就能使用1号筷子了.

于是就不会产生循环等待了

两个线程对于加锁的顺序没有约定, 就容易产生环路等待.

Object lock1 = new Object();
Object lock2 = new Object();
Thread t1 = new Thread() {@Overridepublic void run() {synchronized (lock1) {synchronized (lock2) {// do something...}}}
};
t1.start();
Thread t2 = new Thread() {@Overridepublic void run() {synchronized (lock2) {synchronized (lock1) {// do something...}}}
};
t2.start();

约定好先获取 lock1, 再获取 lock2 , 就不会环路等待.

Object lock1 = new Object();
Object lock2 = new Object();
Thread t1 = new Thread() {@Overridepublic void run() {synchronized (lock1) {synchronized (lock2) {// do something...}}}
};
t1.start();
Thread t2 = new Thread() {@Overridepublic void run() {synchronized (lock1) {synchronized (lock2) {// do something...}}}
};
t2.start();

相关文章:

死锁是什么?死锁是如何产生的?如何破除死锁?

1. 死锁是什么 多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 2. 死锁的三种典型情况 一个线程, 一把锁, 是不可重入锁, 该线程针对这个锁连续加锁两次, 就会出现死锁. 两个线程…...

给虚拟机配置静态id地址

1.令人头大的原因 当连接虚拟机的时候 地址不一会就改变,每次都要重新输入 2.配置虚拟机静态id地址 打开命令窗口执行 : vim /etc/sysconfig/network-scripts/ifcfg-ens33 按下面操作修改 查看自己子网掩码 3.重启网络 命令行输入 systemctl restart netwo…...

Mybatis-Plus 租户使用

Mybatis-Plus 租户使用 文章目录 Mybatis-Plus 租户使用一. 前言1.1 租户存在的意义1.2 租户框架 二. Mybatis-plus 租户2.1 租户处理器2.2 前置准备1. 依赖2. 表及数据准备3. 代码生成器 2.3 使用 三. 深入使用3.1 前言3.2 租户主体设值,取值3.3 部分表全量db操作3…...

vue el-table (固定列+滚动列)【横向滚动条】确定滚动条是在列头还是列尾

效果图&#xff1a; 代码实现&#xff1a; html&#xff1a; <script src"//unpkg.com/vue2/dist/vue.js"></script> <script src"//unpkg.com/element-ui2.15.14/lib/index.js"></script> <div id"app" style&quo…...

⑦【Redis GEO 】Redis常用数据类型:GEO [使用手册]

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ Redis GEO ⑦Redis GEO 基本操作命令1.geoadd …...

LeetCode 2304. 网格中的最小路径代价:DP

【LetMeFly】2304.网格中的最小路径代价&#xff1a;DP 力扣题目链接&#xff1a;https://leetcode.cn/problems/minimum-path-cost-in-a-grid/ 给你一个下标从 0 开始的整数矩阵 grid &#xff0c;矩阵大小为 m x n &#xff0c;由从 0 到 m * n - 1 的不同整数组成。你可以…...

c 实用化的文本终端实时显示摄像头视频

因为采用yuv格式&#xff0c;帧率都很低。图像会拖影。把图像尺寸尽量缩小&#xff0c;能大大改善。现在最麻烦的是图像上有黑色的闪影&#xff0c;不知是为啥&#xff1f;如是framebuffer引起的就无解了。终于找到问题了&#xff0c;是在显示前加了一条用黑色清屏造成的&#…...

CSS中常用的伪类选择器

一 、伪类&#xff08;不存在的类&#xff0c;特殊的类&#xff09; -伪类用来描述一个元素的特殊状态 比如&#xff1a;第一个元素&#xff0c;被点击的元素&#xff0c;鼠标移入的元素 -特点&#xff1a;一般请情况下&#xff0c;使用&#xff1a;开头 1、 :first-child …...

【python学习】中级篇-数据库操作:SQLite

SQLite是一个轻量级的数据库引擎&#xff0c;它可以嵌入到各种应用程序中。以下是SQLite的基本用法&#xff1a; 创建数据库文件 import sqlite3# 连接到一个不存在的数据库文件&#xff0c;如果文件不存在&#xff0c;将会自动创建一个新的数据库文件 conn sqlite3.connect…...

汇编-PROTO声明过程

64位汇编 64 模式中&#xff0c;PROTO 伪指令指定程序的外部过程&#xff0c;示例如下&#xff1a; ExitProcess PROTO ;指定外部过程&#xff0c;不需要参数.code main PROCmov ebx, 0FFFFFFFFh mov ecx,0 ;结束程序call ExitProcess ;调用外部过程main ENDP END 32位…...

MYSQL事务操作

...

自动化测试——自动卸载软件

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…...

Linux - 系统调用(syscall)

说明 基于riscv64 soc linux_5.10.4平台&#xff0c;通过新增一个系统调用深入了解下系统调用实现原理。 简介 Linux 软件运行环境分为用户空间和内核空间&#xff0c;默认情况下&#xff0c;用户进程无法访问内核&#xff0c;既不能访问内核所在的内存空间&#xff0c;也不…...

c语言-冒泡排序

冒泡排序原理&#xff1a; 冒泡排序是一种简单直观的排序算法&#xff0c;它重复地遍历待排序的元素序列&#xff0c;比较相邻的两个元素&#xff0c;如果它们的顺序不符合要求&#xff08;例如升序要求前面的元素小于后面的元素&#xff09;&#xff0c;则交换它们的位置。遍历…...

Mysql面经

Select语句的执行顺序 1、from 子句组装来自不同数据源的数据&#xff1b; 2、where 子句基于指定的条件对记录行进行筛选&#xff1b; 3、group by 子句将数据划分为多个分组&#xff1b; 4、使用聚集函数进行计算&#xff1b;AVG() SUM() MAX() MIN() COUNT() 5、使用 havin…...

1panel可视化Docker面板安装与使用

官网地址1Panel - 现代化、开源的 Linux 服务器运维管理面板 文章目录 目录 文章目录 前言 一、环境准备 二、使用步骤 1.安装命令 2.一些命令 3.使用 总结 前言 一、环境准备 虚拟机centos 已经安装好docker和 Docker Compose 或者都没安装 1panel会帮你自动安装 二、使用…...

es6中的import导入模块 和 export导出模块

es6中的import导入模块 和 export导出模块 一、定义二、使用1.默认导出导入2..命名导出导入3.命名导出&#xff08;Named Export&#xff09;与默认导出&#xff08;Default Export&#xff09;结合使用 三、总结 一、定义 功能&#xff1a;用于导入和导出模块的内容。 静态加载…...

WordPress插件开发教程手册 — 钩子(Hooks)

钩子是用一段代码添加/修改另外一段代码的方式&#xff0c;是 WordPress插件和主题与 WordPress 内核交互的基础&#xff0c;钩子在 WordPress 内核中也被广泛使用。WordPress 中有两种钩子&#xff0c;Action 和 Filter。使用钩子时&#xff0c;我们需要先编写一个自定义函数作…...

Python开发运维:Celery连接Redis

目录 一、理论 1.Celery 二、实验 1.Windows11安装Redis 2.Python3.8环境中配置Celery 3.celery的多目录结构异步执行 4.celery简单结构下的定时任务 三、问题 1.Celery命令报错 2.执行Celery命令报错 3.Win11启动Celery报ValueErro错误 4.Pycharm 无法 import 同目…...

JSP:JDBC

JDBC&#xff08;Java Data Base Connectivity的缩写&#xff09;是Java程序操作数据库的API&#xff0c;也是Java程序与数据库相交互的一门技术。 JDBC是Java操作数据库的规范&#xff0c;由一组用Java语言编写的类和接口组成&#xff0c;它对数据库的操作提供基本方法&#…...

Layui layer.tips提示框怎么设置方向和颜色

...

鸿蒙游戏,会不会重演微信小游戏的爆发?

网罗开发&#xff08;小红书、快手、视频号同名&#xff09;大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等方…...

别再死记硬背LLC公式了!用这个仿真模型,手把手带你理解谐振腔的感性区与容性区

别再死记硬背LLC公式了&#xff01;用这个仿真模型&#xff0c;手把手带你理解谐振腔的感性区与容性区 在电源设计领域&#xff0c;LLC谐振变换器因其高效率特性广受青睐&#xff0c;但许多工程师在实际调试中常陷入公式推导的泥潭。本文将通过LTspice仿真&#xff0c;带您直观…...

终极RPG Maker解密工具:3分钟掌握游戏资源提取全攻略

终极RPG Maker解密工具&#xff1a;3分钟掌握游戏资源提取全攻略 【免费下载链接】RPGMakerDecrypter Tool for decrypting and extracting RPG Maker XP, VX and VX Ace encrypted archives and MV and MZ encrypted files. 项目地址: https://gitcode.com/gh_mirrors/rp/RP…...

告别纸上谈兵:手把手教你用AVL CRUISE M+dSPACE搭建首个硬件在环(HiL)测试环境

从零构建HiL测试台架&#xff1a;AVL CRUISE M与dSPACE实战指南 第一次接触硬件在环&#xff08;HiL&#xff09;测试的工程师常会遇到这样的困境&#xff1a;明明在仿真环境中运行良好的模型&#xff0c;一旦接入真实硬件就问题频出。去年我负责的一个混动变速箱控制单元测试项…...

从CCF A类清单看计算机学科前沿:如何选择你的学术发表阵地

1. CCF A类清单&#xff1a;计算机学术圈的"米其林指南" 第一次看到CCF A类清单时&#xff0c;我正为博士开题选方向发愁。导师甩给我这份列表说&#xff1a;"这就是计算机学界的米其林三星榜单&#xff0c;发一篇能顶三篇普通论文。"后来我才理解&#x…...

千问3.5-2B生产环境部署:supervisor自启配置、日志轮转与异常恢复机制

千问3.5-2B生产环境部署&#xff1a;supervisor自启配置、日志轮转与异常恢复机制 1. 千问3.5-2B模型简介 千问3.5-2B是Qwen系列的小型视觉语言模型&#xff0c;具备图片理解与文本生成能力。这个模型可以&#xff1a; 接收用户上传的图片结合自然语言提示词进行分析完成图片…...

云原生环境中的存储管理:从PV到StorageClass的全面指南

云原生环境中的存储管理&#xff1a;从PV到StorageClass的全面指南 &#x1f525; 硬核开场 各位技术大佬们&#xff0c;今天咱们来聊聊云原生环境中的存储管理。别跟我说你还在为容器存储问题头疼&#xff0c;那都2023年了&#xff01;在云原生时代&#xff0c;存储是Kubernet…...

ChampR:打破英雄联盟数据孤岛,构建智能化游戏决策助手

ChampR&#xff1a;打破英雄联盟数据孤岛&#xff0c;构建智能化游戏决策助手 【免费下载链接】champr &#x1f436; Yet another League of Legends helper 项目地址: https://gitcode.com/gh_mirrors/ch/champr 在英雄联盟的竞技世界中&#xff0c;每个玩家都面临着相…...

暗黑破坏神2存档编辑终极指南:使用d2s-editor打造完美角色

暗黑破坏神2存档编辑终极指南&#xff1a;使用d2s-editor打造完美角色 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 你是否想在暗黑破坏神2中自由调整角色属性、打造理想装备、优化游戏进度&#xff1f;d2s-editor为你提供了完…...