不可重入锁与死锁
不可重入锁确实可能导致死锁,特别是在同一线程尝试多次获取同一把锁时。如果锁是不可重入的,那么线程在第二次尝试获取锁时会永远阻塞,从而导致死锁。
不可重入锁与死锁的关系
不可重入锁不允许同一个线程多次获取同一把锁。在以下情况下,这种限制会导致死锁:
- 递归调用时: 如果一个方法使用了不可重入锁并递归调用自身,那么在递归调用的过程中,线程会尝试重新获取同一把锁,而由于锁是不可重入的,线程会阻塞在第二次锁请求上,最终导致死锁。
- 嵌套调用时: 如果一个方法调用了另一个也需要同一把锁的方法,同样会因为不可重入锁导致死锁。
示例:不可重入锁导致死锁
代码示例:
假设我们有一个不可重入锁:
class NonReentrantLock {private boolean isLocked = false;public synchronized void lock() throws InterruptedException {while (isLocked) {wait(); // 如果锁已经被占用,等待释放}isLocked = true;}public synchronized void unlock() {isLocked = false;notify();}
}public class DeadlockExample {private final NonReentrantLock lock = new NonReentrantLock();public void method1() throws InterruptedException {lock.lock();System.out.println("Method1: Lock acquired");// 调用另一个需要同一把锁的方法method2();lock.unlock();System.out.println("Method1: Lock released");}public void method2() throws InterruptedException {lock.lock(); // 再次尝试获取锁System.out.println("Method2: Lock acquired");lock.unlock();System.out.println("Method2: Lock released");}public static void main(String[] args) {DeadlockExample example = new DeadlockExample();new Thread(() -> {try {example.method1();} catch (InterruptedException e) {e.printStackTrace();}}).start();}
}
运行结果:
程序会在 method2()
尝试获取锁时发生死锁,因为:
method1()
已经持有了不可重入锁。method2()
需要获取同一把锁,但由于锁是不可重入的,线程会阻塞在lock()
调用处。method1()
无法继续执行释放锁,导致死锁。
为什么可重入锁不会导致死锁?
可重入锁允许同一个线程多次获取同一把锁,而不会被阻塞。这是通过计数器机制实现的:
- 当一个线程第一次获取锁时,计数器加1。
- 如果该线程再次获取同一把锁,计数器继续加1。
- 每次释放锁时,计数器减1,只有当计数器归零时,锁才真正释放。
因此,在递归调用或嵌套调用时,线程可以多次安全地获取锁,不会导致死锁。
如何避免不可重入锁导致的死锁?
- 使用可重入锁:
- 替换不可重入锁为可重入锁(例如,Java 中的
ReentrantLock
或使用synchronized
)。
- 替换不可重入锁为可重入锁(例如,Java 中的
- 设计避免嵌套锁定:
- 如果锁是不可重入的,尽量避免在同一线程中多次尝试获取同一把锁。
- 重构代码:
- 如果可能,将涉及不可重入锁的嵌套调用重构为非嵌套调用。
总结
不可重入锁确实会导致死锁,尤其是在递归调用或嵌套调用时。如果代码中存在这种场景,建议使用可重入锁(例如 ReentrantLock
或 synchronized
)来避免死锁问题。
相关文章:
不可重入锁与死锁
不可重入锁确实可能导致死锁,特别是在同一线程尝试多次获取同一把锁时。如果锁是不可重入的,那么线程在第二次尝试获取锁时会永远阻塞,从而导致死锁。 不可重入锁与死锁的关系 不可重入锁不允许同一个线程多次获取同一把锁。在以下情况下&am…...

XXE-Lab靶场漏洞复现
1.尝试登录 输入账号admin/密码admin进行登录,并未有页面进行跳转 2.尝试抓包分析请求包数据 我们可以发现页面中存在xml请求,我们就可以构造我们的xml请求语句来获取想要的数据 3.构造语句 <?xml version"1.0" ?> <!DOCTYPE fo…...
从Windows到Linux:跨平台数据库备份与还原
数据库的备份与还原 目录 引言备份 2.1 备份所有数据库2.2 备份单个数据库2.3 备份多个指定数据库 传输备份文件还原 4.1 还原所有数据库4.2 还原单个数据库4.3 还原多个指定数据库 注意事项拓展 1. 引言 在不同的操作系统间进行数据库迁移时,命令行工具是我们的…...

upload-labs
Win平台靶场 靶场2 教程 教程 教程 pass-01 bash 本pass在客户端使用js对不合法图片进行检查!前端绕过, 禁用前端js代码, 或者上传图片, 抓包改后缀为 php , 后端没有校验 bash POST /Pass-01/index.php HTTP/1.1 Host: 47.122.3.214:8889 Content-Length: 49…...

【西门子PLC.博途】——面向对象编程及输入输出映射FC块
当我们做面向对象编程的时候,需要用到输入输出的映射。这样建立的变量就能够被复用,从而最大化利用了我们建立的udt对象。 下面就来讲讲映射是什么。 从本质上来说,映射就是拿实际物理对象对应程序虚拟对象,假设程序对象是I0.0&…...

牛客周赛 Round 72 题解
本次牛客最后一个线段树之前我也没碰到过,等后续复习到线段树再把那个题当例题发出来 小红的01串(一) 思路:正常模拟,从前往后遍历一遍去统计即可 #include<bits/stdc.h> using namespace std; #define int lo…...

Flux Tools 结构简析
Flux Tools 结构简析 BFL 这次一共发布了 Canny、Depth、Redux、Fill 四个 Tools 模型系列,分别对应我们熟悉的 ControlNets、Image Variation(IP Adapter)和 Inpainting 三种图片条件控制方法。虽然实现功能是相同的,但是其具体…...
0 前言
ArCS作为一个基于Rust的CAD(计算机辅助设计)开源系统,尽管已经有四年未更新,但其设计理念和技术实现仍然具有很高的学习和参考价值。以下是对ArCS项目的进一步分析和解读: 一、项目亮点与技术优势 高效与安全的Rust语…...

ARM嵌入式学习--第八天(PWM)
PWM -PWM介绍 PWM(pulse Width Modulation)简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在测量,通信,工控等方面 PWM的频率 是指在1秒钟内,信号从…...

遇到“REMOTE HOST IDENTIFICATION HAS CHANGED!”(远程主机识别已更改)的警告
连接虚拟机时提示报错: [insocoperhq-soc-cap-raw3 ~]$ ssh root10.99.141.104WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-midd…...

vue3前端组件库的搭建与发布(一)
前言: 最近在做公司项目中,有这么一件事情,很是头疼,就是同一套代码,不同项目,要改相同bug,改好多遍,改的都想吐,于是就想做一个组件库,这样更新一下就全都可…...

COMSOL快捷键及内置函数
文章目录 COMSOL快捷键使用COMSOL算子求最大值和最小值COMSOL内置函数3.1 解析函数3.2 插值函数3.3 分段函数3.4 高斯脉冲函数3.5 斜坡函数3.6 矩形函数3.7 波形函数3.8 随机函数3.9 Matlab函数3.10 SWITCH函数 COMSOL快捷键 Ctrl+/ 可快速打开预定义的物理量列表。…...

HUAWEI-eNSP交换机链路聚合(手动负载分担模式)
配置思路:HUAWEI交换机链路聚合有LACP模式跟手动负载分担模式,本文主打手动负载分担模式:首先交换机-PC之间划分基本vlan,交换机-交换机之间创建链路聚合组,划分端口至链路聚合分组(缺省模式为手动负载分担模式)。结果验证要求同vlan可以ping通,关闭某个聚合端口后仍可…...

番外篇 | Hyper-YOLO:超图计算与YOLO架构相结合成为目标检测新的SOTA !
前言:Hello大家好,我是小哥谈。Hyper-YOLO,该方法融合了超图计算以捕捉视觉特征之间复杂的高阶关联。传统的YOLO模型虽然功能强大,但其颈部设计存在局限性,限制了跨层特征的融合以及高阶特征关系的利用。Hyper-YOLO在骨干和颈部的联合增强下,成为一个突破性的架构。在COC…...

【MATLAB第109期】基于MATLAB的带置信区间的RSA区域敏感性分析方法,无目标函数
【MATLAB第108期】基于MATLAB的带置信区间的RSA区域敏感性分析方法,无目标函数 参考第64期文章【MATLAB第64期】【保姆级教程】基于MATLAB的SOBOL全局敏感性分析模型运用(含无目标函数,考虑代理模型) 创新点: 1、采…...
Bootstrap 表格
Bootstrap 表格 引言 Bootstrap 是一个流行的前端框架,它提供了一套丰富的工具和组件,用于快速开发响应式和移动设备优先的网页。在本文中,我们将重点讨论 Bootstrap 中的表格组件,包括其基本结构、样式以及如何使用 Bootstrap …...

【论文阅读】Computing the Testing Error without a Testing Set
https://blog.csdn.net/qq_40021158/article/details/109485216 可以使用测试集来估计训练集和测试集之间的性能差距,但是要避免过度拟合测试数据几乎是不可能的。 使用隔离的测试集可能会解决此问题,但这需要不断更新数据集,这是一项非常昂贵…...
Visio——同一个工程导出的PDF文件大小不一样的原因分析
现象 在不同电脑,导出来的PDF文件大小不一样。 原因分析 文件小的未将字体嵌入,文件大的已经将字体嵌入了。...

【ETCD】ETCD 架构揭秘:内部各组件概览
ETCD 的主要组件及它们之间的关联关系如下: 目录 1. Client(客户端)2. gRPC 接口3. Etcd Server Main Loop(ETCD 主循环)4. Raft(共识模块)5. Peer Etcd Nodes(ETCD 集群节点&#x…...

Qt WORD/PDF(四)使用 QAxObject 对 Word 替换(QWidget)
关于QT Widget 其它文章请点击这里: QT Widget 国际站点 GitHub: https://github.com/chenchuhan 国内站点 Gitee : https://gitee.com/chuck_chee 姊妹篇: Qt WORD/PDF(一)使用 QtPdfium库实现 PDF 操作 Qt WORD/PDF(二…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...