尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

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

一文详解Java中死锁产生原因、常见场景及排查解决思路(附详细案例代码)
📅 发布时间:2026/6/19 18:01:33

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进程,点击线程,点击检测死锁即可查看

相关新闻

  • 6G真的要来了?中国移动这次把“未来网络”摆到了台前
  • Yandex复杂还原验证码识别
  • Python中的直接赋值、浅拷贝与深拷贝:常见错误案例与深入理解

最新新闻

  • 抖音去水印免费工具推荐:免费软件小程序都能用 - 工具软件使用方法推荐
  • 02梦断代码阅读笔记之一
  • 2026深圳黄金回收门店实力大排名,透明回收、报价公道商家一览 - 奢侈品回收测评
  • Pot-desktop:跨平台翻译与OCR识别的高效开源解决方案
  • 2026佛山翡翠回收盘点:正规鉴定无套路,本地靠谱变现渠道全测评 - 薛定谔的梨花猫
  • MC68HC908GT Flash与ADC模块深度解析与实战编程指南

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号