news 2026/7/11 1:37:17

一文详解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/7/10 15:06:38

从传感器到图表:PHP实现农业数据实时可视化的5个关键步骤

第一章&#xff1a;从传感器到图表的农业数据可视化概述现代农业正逐步迈向数字化与智能化&#xff0c;其中数据可视化在农业生产决策中扮演着关键角色。通过部署环境传感器采集温度、湿度、土壤水分等关键参数&#xff0c;原始数据被转化为直观的图表&#xff0c;帮助农户实时…

作者头像 李华
网站建设 2026/7/10 6:41:48

业务导向型技术日志首日记录(业务中使用的技术栈)

每做完一个项目我都会小做总结后端技术栈总结&#xff0c;以下是项目中使用的所有后端技术及其业务应用情况&#xff1a; xx管理系统后端技术栈总结 1. 核心框架与语言 Java 基础使用&#xff1a;面向对象编程语言&#xff0c;平台无关性&#xff0c;支持多线程、异常处理、…

作者头像 李华
网站建设 2026/7/9 17:34:56

基于SpringBoot + Vue的宠物殡葬网站设计

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

作者头像 李华
网站建设 2026/7/10 3:42:31

基于Uniapp + SpringBoot + Vue的中医个性化养生系统的设计与实现

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

作者头像 李华
网站建设 2026/7/10 12:59:16

亲测有效:打印机驱动程序无法使用的完整解决思路

在日常办公、学习甚至家庭使用中&#xff0c;打印机几乎属于“刚需设备”。可偏偏很多人都遇到过这样一个让人抓狂的提示——打印机驱动程序无法使用。 打印任务发不出去&#xff0c;扫描功能点了没反应&#xff0c;设备管理器里一切看似正常&#xff0c;但就是用不了。更气人…

作者头像 李华
网站建设 2026/7/9 23:02:46

ollama pull qwen:32b命令执行失败原因排查

ollama pull qwen:32b 命令执行失败原因排查与深度解析 在当前大语言模型&#xff08;LLM&#xff09;快速演进的背景下&#xff0c;越来越多企业和开发者开始尝试将高性能模型部署到本地环境&#xff0c;以满足数据隐私、响应速度和定制化能力的需求。Ollama 作为一款专为本地…

作者头像 李华