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

Java-并发编程-死锁


🔍 死锁排查步骤详解(以 Java 应用为例)


1️⃣ 快速确认死锁现象
  • 现象:应用无响应、接口超时、CPU 占用低但线程阻塞。
  • 日志线索:查看日志中是否存在 java.lang.Thread.State: BLOCKEDdeadlock 关键字。

2️⃣ 获取线程转储(Thread Dump)

🔧 方法一:命令行工具

# 查找 Java 进程 PID
jps -l

# 生成线程转储(替换 PID)
jstack -l <PID> > thread_dump.txt

🔧 方法二:JDK 图形化工具

  • 使用 jconsoleVisualVM 连接进程,直接查看线程状态和检测死锁。

3️⃣ 分析线程转储

🔍 关键步骤:

  1. 搜索 deadlock:线程转储开头会标记检测到的死锁。

    Found one Java-level deadlock:
    =============================
    "Thread-1":
      waiting to lock monitor 0x00007f8d6c0038b8 (object 0x000000076ab66e50, a java.lang.Object),
      which is held by "Thread-0"
    "Thread-0":
      waiting to lock monitor 0x00007f8d6c0060b8 (object 0x000000076ab66e60, a java.lang.Object),
      which is held by "Thread-1"
    
  2. 分析线程状态

    • BLOCKED:线程等待获取锁。
    • 持有锁信息locked <0x000000076ab66e50> 表示当前线程持有的锁。
    • 等待锁信息waiting to lock <0x000000076ab66e60> 表示线程正在等待的锁。

4️⃣ 代码复现与调试

🔧 复现死锁代码示例:

public class DeadlockDemo {
    private static final Object lockA = new Object();
    private static final Object lockB = new Object();

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (lockA) {
                try { Thread.sleep(100); } 
                catch (InterruptedException e) {}
                synchronized (lockB) {} // 等待 lockB
            }
        }).start();

        new Thread(() -> {
            synchronized (lockB) {
                synchronized (lockA) {} // 等待 lockA
            }
        }).start();
    }
}

🔍 调试关键点:

  • 锁顺序:检查不同线程是否以相同顺序获取多个锁。
  • 锁粒度:是否过度使用粗粒度锁(如 synchronized 修饰整个方法)。

5️⃣ 预防与解决策略
策略说明
固定锁顺序所有线程按全局固定顺序获取锁(如按对象哈希值排序)避免循环等待。
超时机制使用 tryLock(long timeout, TimeUnit unit) 设置锁获取超时,避免无限等待。
死锁检测通过工具(如 Arthas)定期扫描线程状态,提前预警。
减少锁粒度使用细粒度锁(如 ConcurrentHashMap 分段锁)或乐观锁(CAS)。
避免嵌套锁尽量减少一个线程同时持有多个锁的场景。

6️⃣ 工具增强
  • Arthas:实时监控线程状态,动态追踪锁竞争。
    # 查看当前线程阻塞状态
    thread -b
    
  • JProfiler:图形化分析线程争用和锁持有关系。

📊 死锁分析流程图
应用出现卡顿或无响应 
    → 生成线程转储(jstack/jcmd) 
        → 查找 "deadlock" 或 "BLOCKED" 线程 
            → 分析锁持有/等待链 
                → 修改代码(调整锁顺序/超时机制) 
                    → 测试验证

通过以上步骤,可快速定位并解决死锁问题,确保应用的高可用性。

相关文章:

  • 位运算符实现对数据特定内容的处理
  • 【爬虫基础】第一部分 网络通讯 P1/3
  • 全面掌握Python时间处理
  • 立创实战派ESP32-S3烧录小智AI指南
  • C 获取特定位数的值
  • Web入侵实战分析
  • 经典Embedding方法:Word2Vec与Skip-Gram算法)
  • 如何禁止chrome浏览器自动更新
  • Leetcode:学习记录(二)
  • tcp协议连接,和传输数据
  • 【论文复现】ESRGAN
  • 使用 Certbot 自动获取和更新 Let‘s Encrypt SSL 证书
  • Matlab写入点云数据到Rosbag
  • 基于YOLOv8的人脸识别系统
  • JVM类文件结构深度解析:跨平台基石与字节码探秘
  • Idea新建Package嵌套折叠现象以及如何处理
  • SPO(Self-Supervised Prompt Optimization)自我监督Prompt提示优化的全景指南
  • 2023年全国职业院校技能大赛GZ073网络系统管理赛项赛题第10套模块A:网络构建
  • 解码 NLP:从萌芽到蓬勃的技术蜕变之旅
  • VMware新建虚拟机
  • 欧阳娜娜担任江西吉安文化旅游大使
  • 河北邯郸一酒店婚宴发生火灾:众人惊险逃生,酒店未买保险
  • 中国词学研究会原会长、华东师大教授马兴荣逝世,享年101岁
  • 第一集|《刑警的日子》很生活,《执法者们》有班味
  • 国家税务总局泰安市税务局:山东泰山啤酒公司欠税超536万元
  • 中消协点名新能源汽车行业:定金退款争议频发