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

Java中的死锁


锁的合理使用能够保证共享数据的安全性,但是 使用不当也会可能引起死锁。


1. 死锁概念

死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉那它们都将无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。


2. 死锁原因

  1. 互斥条件(Mutual Exclusion)
    资源一次只能被一个线程独占使用。
  2. 持有并等待(Hold and Wait)
    线程在持有至少一个资源的同时,还在等待其他线程持有的资源。
  3. 不可抢占(No Preemption)
    资源不能被强制释放,只能由持有它的线程主动释放。
  4. 循环等待(Circular Wait)
    存在一个线程等待链,每个线程都在等待下一个线程持有的资源。

当这四个条件同时满足时,死锁必然发生。

3. 死锁演示

下面的一段代码演示了死锁:

public static void main(String[] args) {Object lockA = new Object();Object lockB = new Object();new Thread(() -> {synchronized (lockA) {System.out.println(Thread.currentThread().getName() + ", 获取了🔒A");try {sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lockB) {System.out.println(Thread.currentThread().getName() + ", 获取了🔒B");}}}, "线程1").start();new Thread(() -> {synchronized (lockB) {System.out.println(Thread.currentThread().getName() + ", 获取了🔒B");try {sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}synchronized (lockA) {System.out.println(Thread.currentThread().getName() + ", 获取了🔒A");}}}, "线程2").start();
}

执行结果:


4. 死锁检测

4.1 命令

jps -l

jstack pid

jstack 6612



4.2 图形工具 jconsole


5. 避免死锁

  • 避免一个线程同时获取多个不同的锁
  • 避免一个线程在锁内同时占用多个资源 尽量保证每个锁只占一个资源
  • 尝试使用带超时时间到锁 ,例如 lock.tryLock(timeout) 来替代内部锁机制
  • 对于数据库锁 加锁和解锁必须在同一个数据库连接里,否则会出现解锁失败的情况
  1. 按固定顺序获取锁。
  2. 使用超时机制(tryLock)。
  3. 减少锁的持有时间和粒度。
  4. 利用高级并发工具替代显式锁。

通过合理设计代码结构、遵循锁顺序约定,以及利用Java并发工具包,可有效避免死锁问题。

http://www.xdnf.cn/news/20192.html

相关文章:

  • 使用 MongoDB.Driver 在 C# .NETCore 中实现 Mongo DB 过滤器
  • [数据结构] ArrayList(顺序表)与LinkedList(链表)
  • 万代《宝可梦》主题新品扭蛋公开!史上最大尺寸
  • 机器人控制器开发(传感器层——奥比大白相机适配)
  • 【FastDDS】Layer Transport ( 05-Shared Memory Transport)
  • 天气预报云服务器部署实战
  • 在Java AI项目中实现Function Call功能
  • 计算机毕设大数据方向:基于Spark+Hadoop的餐饮外卖平台数据分析系统【源码+文档+调试】
  • 通过Idea 阿里插件快速部署java jar包
  • 实用向:Linux Shell 脚本实现 CPU / 内存 / 硬盘 + IO / 网络多指标告警(支持 163/QQ/139 邮箱)
  • python调用mysql
  • PDF文件基础-计算机字体
  • 【Luogu_P8118】 「RdOI R3.5」Mystery【Slope Trick】【DP】
  • 深度学习基础概念回顾(Pytorch架构)
  • 【Java实战㉗】Java日志框架实战:Logback与Log4j2的深度探索
  • 大型Go项目中搭建CI/CD流水线
  • 竞价代运营:百度竞价账户托管优化
  • VeeValidate v4 终极指南:精通 Vue 3 组合式 API 表单验证
  • Web Worker 从原理到实战 —— 把耗时工作搬到后台线程,避免页面卡顿
  • 计算机视觉(九):图像轮廓
  • 破局功能割裂、成本高昂、协同低效,遨游天通卫星电话实现一机多能
  • Adobe Illustrator(Ai) 2022矢量设计软件的安装教程与下载地址
  • 【Python自动化】 21.3 Pandas Series 核心数据结构完全指南
  • 如何使显示器在笔记本盖上盖子时还能正常运转
  • windows找不到gpedit.msc(本地组策略编辑器)
  • Docker容器安全最佳实践:镜像扫描、权限控制与逃逸防范
  • Pie Menu Editor V1.18.7.exe 怎么安装?详细安装教程(附安装包)​
  • [linux仓库]性能加速的隐形引擎:深度解析Linux文件IO中的缓冲区奥秘
  • Java并发锁相关
  • LeetCode - 202. 快乐数