news 2026/5/29 23:54:29

一文详解Java中死锁产生原因、常见场景及排查解决思路(附详细案例代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一文详解Java中死锁产生原因、常见场景及排查解决思路(附详细案例代码)

01-死锁的概念

死锁是指两个或两个以上的线程在执行过程中,因抢夺资源而造成的一种互相等待的现象,若无外力干涉,则它们无法再继续推进下去

02-产生原因

  • 系统资源不足
  • 进程运行推进顺序不合适
  • 系统资源分配不当

03-常见死锁场景与示例

3.1嵌套锁顺序不一致

public class DeadLockDemo { static Object a = new Object(); static Object b = new Object(); public static void main(String[] args) { new Thread(() -> { synchronized (a){ System.out.println("t1线程持有a锁,试图获取b锁"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (b){ System.out.println("t1线程获取到b锁"); } } },"t1").start(); new Thread(() -> { synchronized (b){ System.out.println("t2线程持有a锁,试图获取a锁"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (a){ System.out.println("t2线程获取到a锁"); } } },"t2").start(); } }

分析:

  • t1线程执行:先获取a锁,再请求b锁
  • t2线程执行:先获取b锁,再请求a锁
  • 可能形成循环等待

3.2动态锁顺序死锁

public void transfer(Account from, Account to, int amount) { synchronized (from) { synchronized (to) { from.withdraw(amount); to.deposit(amount); } } }

分析:

如果两个线程同时调用transfer(),但参数顺序相反:

  • 线程A:transfer(account1, account2, 100)
  • 线程B:transfer(account2, account1, 200)

可能产生死锁

3.3资源死锁(如线程池任务相互等待)

ExecutorService executor = Executors.newFixedThreadPool(2); Future<?> future1 = executor.submit(() -> { Future<?> future2 = executor.submit(() -> System.out.println("Task2")); future2.get(); // 等待任务2完成 }); future1.get(); // 等待任务1完成

分析:

  • 线程池只有两个线程
  • 任务1提交任务2并等待任务2完成,任务2等待线程池空闲
  • 若任务2无法执行,任务1也无法完成,形成死锁

04-如何避免死锁

4.1 固定锁顺序

始终按全局一致顺序获取锁

public void transfer(Account a, Account b, int amount) { Object firstLock = a.id < b.id ? a : b; Object secondLock = a.id < b.id ? b : a; synchronized (firstLock) { synchronized (secondLock) { // 操作 } } }

4.2使用超时机制

tryLock()替代synchronized,设置超时时间

if (lock1.tryLock(100, TimeUnit.MILLISECONDS)) { try { if (lock2.tryLock(100, TimeUnit.MILLISECONDS)) { try { // 操作 } finally { lock2.unlock(); } } } finally { lock1.unlock(); } }

4.3 避免嵌套锁

尽量只持有一个锁,或 将多个锁封装为一个大锁

05-如何排查死锁

5.1 纯命令

  • jps -l—> 相当于 java ps -ef -l —>查看本地系统中所有正在运行的 Java 进程
  • jstack 进程编号—>查看进程堆栈信息

5.2 图形化

jconsole —>win + R 输入 jconsole,连接对应的Java进程,点击线程,点击检测死锁即可查看

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 4:35:00

HTTP网络巩固知识基础题(1)

1. HTTP 是什么协议? A. 应用层协议 B. 传输层协议 C. 网络层协议 D. 数据链路层协议 答案:A 解析: HTTP(HyperText Transfer Protocol)是应用层协议,运行在TCP之上,用于Web浏览器和服务器之间的通信。 2. HTTP 默认端口号是多少? A. 21 B. 25 C. 80 D. 443 答案:…

作者头像 李华
网站建设 2026/5/22 5:49:35

GE PLE3PNLBG02

GE PLE3PNLBG02 产品信息GE PLE3PNLBG02 是通用电气&#xff08;GE&#xff09;生产的一款家用电器部件或配件&#xff0c;可能涉及照明、插座或其他电气设备。由于型号较为具体&#xff0c;需结合产品类型进一步确认功能或用途。常见应用场景该型号可能用于以下场景&#xff1…

作者头像 李华
网站建设 2026/5/30 4:21:45

业务导向型技术日志首日记录

基于过往业务的个人技术日志—第一天 业务背景回顾 今天开始整理过往参与的核心项目技术细节&#xff0c;第一个回顾的是2022年Q2负责的电商促销系统性能优化项目。该系统承载公司618大促活动&#xff0c;峰值QPS需支撑5万&#xff0c;原系统在压测时出现响应延迟飙升和数据库连…

作者头像 李华
网站建设 2026/5/29 4:13:13

LobeChat与FastGPT对比:两款开源聊天界面的核心差异

LobeChat 与 FastGPT 对比&#xff1a;两款开源聊天界面的核心差异 在大语言模型&#xff08;LLM&#xff09;快速普及的今天&#xff0c;越来越多开发者和企业希望将这些强大的模型融入实际业务场景。然而&#xff0c;原始模型本身并不具备用户交互能力——它更像一个“黑盒引…

作者头像 李华
网站建设 2026/5/27 7:29:47

LobeChat如何帮助初创公司低成本启动AI产品线?

LobeChat如何帮助初创公司低成本启动AI产品线&#xff1f; 在生成式AI席卷各行各业的今天&#xff0c;许多初创团队手握强大的大模型能力&#xff0c;却卡在了“如何让用户用起来”这一关。一个训练得再出色的模型&#xff0c;如果缺乏直观、稳定的交互界面&#xff0c;也难以转…

作者头像 李华
网站建设 2026/5/28 3:01:48

基于Uniapp + SpringBoot + Vue的动态个人博客系统的设计与实现

文章目录前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论五、项目代码参考六、数据库代码参考七、项目论文示例结语前言 &#x1f49b;博主介绍&#…

作者头像 李华