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

Java并发避坑:一文搞懂死锁的本质、实例与解决方案

在Java并发编程中锁是我们处理共享资源、避免线程安全问题的“利器”。它用法简单、易于理解无论是synchronized关键字还是Lock接口都能帮我们轻松实现线程间的同步。但凡事有利有弊锁的不当使用很容易引发一个致命问题——死锁。一旦死锁发生相关线程会陷入无限等待系统功能直接瘫痪排查起来也颇为棘手。今天就带大家从头到尾吃透死锁从“是什么”“怎么复现”“为什么会出现”到“怎么避免”“出现了怎么办”全程干货新手也能轻松看懂。一、什么是死锁用通俗的例子讲明白先抛开复杂的概念我们用一个生活中的场景理解死锁两个人吃饭每人手里都拿着一把叉子却都需要对方手里的勺子才能开动。两个人都不肯先放下自己手里的叉子也拿不到对方的勺子就这么一直僵持着——这就是死锁的本质。对应到Java线程中死锁的定义是两个或两个以上的线程为了争抢同一个或多个共享资源陷入互相等待的状态。在没有外部干预的情况下这些线程会一直阻塞无法继续执行最终导致程序卡死。再举个线程层面的具体例子有ThreadA和ThreadB两个线程它们都需要获取LOCK1和LOCK2两个锁才能完成任务。ThreadA先获取了LOCK1锁住资源AThreadB先获取了LOCK2锁住资源B接下来ThreadA想获取LOCK2资源B但此时LOCK2被ThreadB持有ThreadA只能等待而ThreadB想获取LOCK1资源A但LOCK1被ThreadA持有ThreadB也只能等待。双方都不肯释放自己已持有的锁也无法获取对方的锁死锁就产生了。二、代码复现手把手带你看死锁现场光说不练假把式下面用一段简单的Java代码直接复现死锁场景大家可以复制到本地运行直观感受一下死锁的效果。public class ConcurrencyTest { // 定义两个共享资源锁对象锁只能锁引用数据类型 public static Object A new Object(); public static Object B new Object(); public static void main(String[] args) { // 线程1先获取A再尝试获取B new Thread(()-{ synchronized (A){ System.out.println(Thread.currentThread().getName()获取了资源A的锁); try { // 睡眠1秒故意给线程2获取B的时间线程睡眠会立刻让出CPU睡眠期间线程不在就绪队列CPU对其不可选中 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 尝试获取B此时B已被线程2持有进入阻塞队列竞争失败进阻塞队列 synchronized (B){ System.out.println(Thread.currentThread().getName()获取了资源B的锁); } } }).start(); // 线程2先获取B再尝试获取A与线程1的锁获取顺序相反是死锁的关键 new Thread(()-{ synchronized (B){ // 这里有个小bug原代码打印错误修正为“获取了资源B的锁” System.out.println(Thread.currentThread().getName()获取了资源B的锁); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 尝试获取A此时A已被线程1持有进入阻塞队列 synchronized (A){ System.out.println(Thread.currentThread().getName()获取了资源A的锁); } } }).start(); } }运行这段代码后你会发现控制台只打印出两句“获取资源锁”的日志之后程序就卡住了——这就是死锁发生了。两个线程都处于阻塞状态互相等待对方释放锁永远无法继续执行。补充如何查看死锁信息当程序卡住怀疑是死锁时我们可以通过JDK自带的工具排查步骤非常简单步骤1用jps命令查询所有Java线程信息。打开CMD或终端输入jps会列出当前运行的Java进程ID和进程名找到我们运行的ConcurrencyTest对应的进程ID。步骤2用jstack命令查看线程详情。输入jstack 进程ID把进程ID替换成第一步查到的数字会输出该进程下所有线程的状态信息。步骤3定位死锁。查看输出结果会发现两个线程的状态都是BLOCKED阻塞而且在日志的最后会明确提示“Found one Java-level deadlock”帮我们直接定位到死锁的线程和锁资源。三、深挖本质产生死锁的4个必要条件死锁不是随便就能发生的它的产生必须同时满足4个必要条件缺一不可。只有理解这4个条件我们才能找到避免和解决死锁的突破口。互斥使用共享资源比如上面的A和B只能被一个线程占用。这是锁的核心特性——锁的作用就是保证资源的互斥访问所以这个条件是无法被破坏的。请求和保持条件线程已经获取了一个或多个共享资源在等待其他资源时不会释放自己已持有的资源。比如ThreadA获取了A之后等待B时仍然抱着A不放手这是死锁的重要诱因。不可抢占条件其他线程不能强行抢占一个线程已经持有的资源。也就是说ThreadA持有的A锁除非ThreadA自己释放否则ThreadB无法强制夺取。循环等待多个线程之间形成互相等待的闭环。比如ThreadA等待ThreadB持有的资源ThreadB等待ThreadA持有的资源两者互相僵持形成循环。记住只要破坏这4个条件中的任意一个死锁就不会发生。而由于“互斥使用”是锁的固有特性无法破坏所以我们的重点的是破坏另外3个条件。四、防患于未然如何避免死锁死锁一旦发生只能通过外部干预解决比如重启程序、杀死线程不仅影响用户体验还可能造成数据丢失。所以最好的方式就是在写代码时主动避免死锁的产生。结合上面的3个可破坏条件给大家3个实用的避免技巧破坏“请求和保持”条件一次性申请所有所需资源。线程在执行任务前先一次性获取所有需要的锁资源要么全部获取成功开始执行要么获取失败就等待所有资源释放后再重新申请不持有部分资源去等待其他资源。破坏“不可抢占”条件主动释放已持有资源。如果线程已经持有了部分资源再去申请其他资源时发现申请失败就主动释放自己已持有的所有资源然后重新尝试申请避免抱着资源僵持。破坏“循环等待”条件按固定顺序申请锁资源。给所有的锁资源编号比如给A编号1给B编号2所有线程都按照“从小到大”或固定的其他顺序的编号去申请锁这样就不会出现循环等待的情况。比如上面的代码只要让两个线程都先申请A编号1再申请B编号2死锁就不会发生。五、亡羊补牢出现死锁后怎么办如果不小心写出了死锁代码程序已经卡住了该怎么解决主要分两步紧急处理重启程序或杀死死锁线程。这是最直接、最快速的方式能立刻解除死锁恢复系统功能。但这种方式属于“治标不治本”只能应急不能解决根本问题。根本解决排查并修改代码。用前面提到的jstack命令导出线程的dump日志定位到具体发生死锁的代码片段然后根据前面的避免技巧修改代码破坏死锁的3个可破坏条件之一。比如调整锁的申请顺序、一次性申请所有资源等从根源上避免死锁再次发生。最后补充2个关键注意点避坑必看线程睡眠Thread.sleep()会立刻让出CPU睡眠期间线程不在就绪队列中CPU不会选中它执行但不会释放已持有的锁资源——这也是我们上面代码能复现死锁的关键睡眠期间线程仍然抱着已获取的锁。锁只能锁引用数据类型比如Object、自定义对象不能锁基本数据类型比如int、long因为基本数据类型会自动装箱/拆箱每次锁的都是不同的对象起不到同步作用。线程竞争锁失败时会进入阻塞队列等待持有锁的线程释放锁后再重新竞争锁。总结死锁是Java并发编程中的常见“坑”但只要理解它的本质4个必要条件就能轻松找到应对方法优先通过“一次性申请资源”“按顺序申请锁”等方式避免死锁若死锁已经发生就用jstack排查修改代码从根源解决。

相关文章:

Java并发避坑:一文搞懂死锁的本质、实例与解决方案

在Java并发编程中,锁是我们处理共享资源、避免线程安全问题的“利器”。它用法简单、易于理解,无论是synchronized关键字还是Lock接口,都能帮我们轻松实现线程间的同步。但凡事有利有弊,锁的不当使用,很容易引发一个致…...

腾讯零信任提示系统的优化经验:提示工程架构师的参考!

腾讯零信任提示系统的优化经验:提示工程架构师的参考! 1. 引入与连接 1.1 引人入胜的开场 在当今数字化的时代,企业的网络安全面临着前所未有的挑战。想象一下,一家大型互联网公司,每天有成千上万的员工通过各种设备接…...

为什么你的网速总是不达标?从带宽、吞吐量到时延的完整解析

为什么你的网速总是不达标?从带宽、吞吐量到时延的完整解析 每次打开视频网站缓冲转圈,或是游戏突然卡顿,总会让人忍不住怀疑:明明办理了200M宽带,为什么实际体验远不如预期?这背后涉及三个关键概念&#x…...

python+flask+vue3企业员工加班调休考勤请假管理系统

目录技术栈选择系统功能模块数据库设计后端实现前端实现系统安全部署方案项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作技术栈选择 Python Flask 作为后端框架,Vue 3 作为前端框架,数据库使用 MySQL 或…...

python+flask+vue3云南旅游景点酒店预订系统网站

目录技术栈选择系统模块划分前后端交互设计数据库关键表结构地图集成方案支付对接方案部署实施方案性能优化措施项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作技术栈选择 后端采用Python Flask框架,轻量灵活适合快…...

永磁同步电机三矢量MPC模型预测电流控制 参考文献:《永磁同步电机三矢量模型预测电流控制_徐艳...

永磁同步电机三矢量MPC模型预测电流控制 参考文献:《永磁同步电机三矢量模型预测电流控制_徐艳平》 (1)采用id0,速度环 PI 控制器的输出作为q轴电流的给定。 在核心模块 TV-MPCC 中,首先根据电流给定值和反馈值计算三个…...

基于matlab的无人机路径规划,包括2D路径和3D路径,三种优化算法,分别是蝙蝠算法(BA)...

基于matlab的无人机路径规划,包括2D路径和3D路径,三种优化算法,分别是蝙蝠算法(BA)、蝙蝠算法融合差分进化算法(DEBA)、结合人工势场方法的改进混沌蝙蝠算 法(CPFIBA)。 输出距离迭代曲线和规划的路径。无人…...

救命神器!8个一键生成论文工具测评:多场景适配,开题报告+毕业论文+科研写作全搞定

在学术研究与论文写作日益数字化的今天,无论是高校学生还是科研工作者,都面临着选题困难、文献检索繁琐、内容检测无从下手等多重挑战。2026年,随着AI技术的不断进步,越来越多的写作辅助工具涌现,但如何在众多产品中找…...

杨辉三角(Pascal‘s Triangle)

什么是杨辉三角? 杨辉三角(Pascal’s Triangle)这是一个在数学中非常经典的数字三角形,具有许多有趣的性质和应用。 是一个由数字组成的三角形阵列,其中每个数等于它上方两数之和。它的历史可以追溯到中国古代数学家杨…...

相场法在水力压裂模拟中越来越火,尤其是COMSOL这种多物理场耦合神器。今天咱们拆解几个典型工况,手把手看裂缝怎么在代码里“长“出来。先拿最简单的单裂缝开刀——

COMSOL 相场法与水力压裂 案例一:单一裂缝延伸; 案例二:两簇压裂; 案例三:三簇压裂-对称; 案例四:三簇压裂-完全; 案例五:水力裂缝与垂直天然裂缝相交; 案例六…...

SQLite - Perl:深入浅出数据库编程实践

SQLite - Perl:深入浅出数据库编程实践 引言 SQLite 是一种轻量级的数据库,以其简洁的设计和强大的功能,在嵌入式系统、移动应用以及个人项目中得到了广泛应用。Perl,作为一种强大的脚本语言,也因其灵活性而深受开发者喜爱。本文将深入探讨SQLite与Perl的结合,展示如何…...

Python数据分析/机器学习中的内存陷阱:用pandas处理大数据时如何避免OOM(附memory_profiler使用技巧)

Python数据分析中的内存优化实战:从OOM崩溃到高效处理GB级数据 当你面对一份20GB的CSV文件时,pandas的read_csv()可能会成为压垮内存的最后一根稻草。上周我的Jupyter Notebook内核就因此崩溃了三次——每次都是在等待了半小时后看到令人绝望的MemoryErr…...

不用Chrome也能用Vue DevTools:Edge浏览器专属配置指南

Edge浏览器专属配置:Vue DevTools高效调试指南 作为微软力推的新一代浏览器,Edge凭借其卓越的性能和与Windows系统的深度整合,正吸引着越来越多的开发者迁移。对于Vue开发者而言,Edge上运行Vue DevTools的体验丝毫不逊色于Chrome&…...

保姆级教程:用QGIS 3.34处理OpenStreetMap中国路网数据,从下载.shp到筛选出城市道路

零基础实战:用QGIS 3.34精准提取中国城市路网数据全流程 当你第一次面对OpenStreetMap的海量数据时,是否曾被复杂的文件格式和GIS软件的操作界面劝退?作为城市规划专业的在读研究生,我曾经花了整整两周时间摸索如何从OSM中提取成都…...

计算机毕业设计 java 疫情防控形势下的高校食堂订餐管理系统 SpringBoot 高校食堂疫情防控订餐系统 JavaWeb 疫情期间高校餐饮订餐管理平台

计算机毕业设计 java 疫情防控形势下的高校食堂订餐管理系统 dd4eq9,末尾的数字和英文也要加上 (配套有源码 程序 mysql 数据库 论文)本套源码可以先看具体功能演示视频领取,文末有联 xi 可分享疫情防控期间,高校食堂作…...

计算机毕设 java 辽宁工大毕业论文管理系统 Java 高校毕业论文全流程管理平台开发 基于 SpringBoot 的毕业论文选题与答辩管理系统实现

计算机毕设 java 辽宁工大毕业论文管理系统 655cp9(配套有源码 程序 mysql 数据库 论文)本套源码可以先看具体功能演示视频领取,文末有联 xi 可分享随着高等教育规模的扩大和信息化技术的发展,高校毕业论文管理工作面临着流程繁琐…...

计算机毕业设计 java 学校社团活动管理系统 JavaWeb 校园社团事务管理平台 基于 SpringBoot 的高校社团活动统筹系统

计算机毕业设计 java 学校社团活动管理系统 v951y9,末尾的数字和英文也要加上 (配套有源码 程序 mysql 数据库 论文)本套源码可以先看具体功能演示视频领取,文末有联 xi 可分享 随着互联网技术的普及和教育信息化的推进&#xff…...

计算机毕业设计 java 疫苗预约系统 基于 JavaWeb 的智能疫苗预约平台 SpringBoot 疫苗接种预约管理系统

计算机毕业设计 java 疫苗预约系统 149fx9,末尾的数字和英文也要加上 (配套有源码 程序 mysql 数据库 论文)本套源码可以先看具体功能演示视频领取,文末有联 xi 可分享随着网络科技的飞速发展和人们健康意识的提升,传统…...

2026年GPT-5.2硬核实战:从数学猜想证明到国内稳定接入全攻略

GPT-5.2是OpenAI于2025年12月发布的紧急迭代版本,其Pro版本已在2026年1月独立攻克了困扰数学界46年的Erdős猜想第281号问题,获得菲尔兹奖得主陶哲轩的认证。这是AI首次在基础数学领域做出原创性贡献。对于国内开发者和技术爱好者,目前最便捷…...

580万台登顶,割草机暴涨63.8%:2025全球清洁机器人座次表,国产包揽前五

以前聊起扫地机器人,大家可能先想到的是iRobot这类海外老牌。但看完IDC刚更新的2025年成绩单,这印象得彻底翻篇了——全球前五名清一色全是国产厂商,石头科技以580万台的出货量、17.7%的份额稳坐头把交椅,科沃斯、追觅、小米、云鲸紧随其后。曾经的优势选手iRobot,这次连前…...

海思发布自研5000万像素CIS芯片,国产高端影像传感器迈入全栈自研时代

2026年3月,在全球半导体与影像产业界备受关注的时刻,华为旗下核心半导体子公司海思半导体(HiSilicon)正式对外公开其首款全栈自研的高端CMOS图像传感器(CIS)芯片。此举标志着华为在完成系统级芯片(SoC)与操作系统的自主化布局后,成功将技术版图延伸至影像链路的最底层…...

索尼CMOS图像传感器良率危机与全球供应链变局深度解析

近期,索尼半导体位于日本长崎技术中心(TEC)的CMOS图像传感器生产遭遇严重良率瓶颈,这一危机正对其核心客户苹果的供应链稳定性构成实质性威胁。作为全球图像传感器市场占据51.6%份额的绝对领导者,索尼此次生产困境不仅暴露了其快速扩张过程中的组织性缺陷,更可能成为全球…...

降AI工具花了钱没效果怎么办?比话的退款承诺让你零风险

降AI工具花了钱没效果怎么办?比话的退款承诺让你零风险 这个问题每到毕业季就会被问一遍。群里隔三差五就有人发消息:“花了XX块钱降AI,结果AI率还是30%多,怎么办?” 答案取决于你用的是哪个工具。有些工具没有任何售后…...

【2025最新】基于SpringBoot+Vue的农事管理系统管理系统源码+MyBatis+MySQL

💡实话实说:CSDN上做毕设辅导的都是专业技术服务,大家都要生活,这个很正常。我和其他人不同的是,我有自己的项目库存,不需要找别人拿货再加价。我就是个在校研究生,兼职赚点饭钱贴补生活费&…...

微信可以用龙虾了!LobsterAI有道龙虾成国内首批接入微信“桌面级Agent”

3月22日,微信官宣 ClawBot 插件正式上线。被誉为“中国版OpenClaw”的桌面级智能体Agent、国内大厂首个开源龙虾——LobsterAI有道龙虾发布新版,率先实现微信接入。用户现可通过微信直接向 Lobster AI下达指令并获取执行结果。此前,LobsterAI…...

翻译后修饰组学:磷酸化、糖基化、泛素化修饰的富集与鉴定技术

点击 “AladdinEdu,你的AI学习实践工作坊”,注册即送-H卡级别算力,沉浸式云原生集成开发环境,80G大显存多卡并行,按量弹性计费,教育用户更享超低价。 摘要:翻译后修饰(PTM&#xff0…...

定量蛋白质组学:iTRAQ、TMT、SILAC与标记-free方法的统计分析与比较

点击 “AladdinEdu,你的AI学习实践工作坊”,注册即送-H卡级别算力,沉浸式云原生集成开发环境,80G大显存多卡并行,按量弹性计费,教育用户更享超低价。 摘要:定量蛋白质组学旨在精确测定蛋白质在不…...

蛋白质鉴定算法:从数据库搜索到从头测序,Mascot、SEQUEST、MaxQuant的工作机制

点击 “AladdinEdu,你的AI学习实践工作坊”,注册即送-H卡级别算力,沉浸式云原生集成开发环境,80G大显存多卡并行,按量弹性计费,教育用户更享超低价。 摘要:蛋白质鉴定是蛋白质组学的核心任务&am…...

质谱基础与蛋白质组学:MALDI-TOF、ESI-MS/MS——肽段鉴定与定量的原理

点击 “AladdinEdu,你的AI学习实践工作坊”,注册即送-H卡级别算力,沉浸式云原生集成开发环境,80G大显存多卡并行,按量弹性计费,教育用户更享超低价。 摘要:质谱技术已成为蛋白质组学研究的核心工…...

PFC 与 OpenFOAM 耦合流化床求解中乱流现象探究

pfc与OpenFOAM耦合流化床求解,颗粒数量较少,但也出现了乱流在 PFC(Particle Flow Code)与 OpenFOAM 耦合进行流化床求解的过程中,本以为颗粒数量较少的情况下,模拟过程会相对顺利,然而却出现了乱…...