Java使用jstack排查死锁(面试考点)

 更新时间:2026年04月02日 08:41:28   作者:砍材农夫  
jstack 是 JDK 自带的命令行工具,用于生成 Java 进程的线程快照,通过分析线程快照,可以快速定位死锁问题,下面就来详细的介绍一下,感兴趣的可以了解一下

jstack 是 JDK 自带的命令行工具,用于生成 Java 进程的线程快照(thread dump)。通过分析线程快照,可以快速定位死锁问题。

1. 获取 Java 进程 ID

首先,找到目标 Java 进程的 PID(进程 ID)。使用 jps 命令:

jps -l

输出示例:

12345 com.example.MyApplication
67890 sun.tools.jps.Jps

记录下应用进程的 PID,例如 12345

2. 生成线程快照

使用 jstack 命令生成线程快照:

jstack <pid> > thread_dump.txt

例如:

jstack 12345 > thread_dump.txt

如果应用因死锁导致无响应,可以添加 -l 选项(显示锁信息):

jstack -l 12345 > thread_dump.txt

注意:在某些环境下(如容器),可能需要使用 sudo 或以应用运行用户身份执行。

3. 分析线程快照

打开生成的 thread_dump.txt,查找死锁信息。

3.1 查找死锁摘要

jstack 会在线程快照末尾自动检测并输出死锁摘要,类似:

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007f8b5c00a5a8 (object 0x00000000d5f6e3a0, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007f8b5c00b0b0 (object 0x00000000d5f6e3b0, a java.lang.Object),
  which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
        at com.example.DeadlockExample.method2(DeadlockExample.java:25)
        - waiting to lock <0x00000000d5f6e3a0> (a java.lang.Object)
        - locked <0x00000000d5f6e3b0> (a java.lang.Object)
        at com.example.DeadlockExample.run(DeadlockExample.java:15)
"Thread-0":
        at com.example.DeadlockExample.method1(DeadlockExample.java:18)
        - waiting to lock <0x00000000d5f6e3b0> (a java.lang.Object)
        - locked <0x00000000d5f6e3a0> (a java.lang.Object)
        at com.example.DeadlockExample.run(DeadlockExample.java:10)

3.2 手动分析线程堆栈

如果没有自动摘要(例如使用 jstack 的旧版本),可以手动查找以下特征:

  • BLOCKED 状态:线程状态为 BLOCKED(在 java.lang.Thread.State 中)
  • 等待锁:堆栈中包含 waiting to lock <0x...> 和 locked <0x...>

找出相互等待锁的线程对,即线程 A 持有锁 L1 等待锁 L2,线程 B 持有锁 L2 等待锁 L1。

4. 解读死锁信息

从摘要中可以获取:

  • 死锁线程名称:Thread-1 和 Thread-0
  • 锁对象地址:<0x00000000d5f6e3a0> 和 <0x00000000d5f6e3b0>
  • 持有与等待关系:
    • Thread-1 持有 <0x...b0>,等待 <0x...a0>
    • Thread-0 持有 <0x...a0>,等待 <0x...b0>
  • 代码位置:具体到哪个类的哪一行(如 DeadlockExample.java:25)

5. 解决死锁

根据堆栈定位到代码,常见解决方式:

  • 调整锁顺序:确保所有线程以相同的顺序获取锁
  • 使用 tryLock:尝试获取锁,超时则释放已持有的锁
  • 减少锁粒度:缩小同步块范围
  • 使用更高层次的并发工具:如 ReentrantLock、StampedLock、ConcurrentHashMap 等

6. 完整示例

以下是一个简单的死锁代码及使用 jstack 排查的演示。

6.1 死锁代码

public class DeadlockExample implements Runnable {
    private final Object lock1 = new Object();
    private final Object lock2 = new Object();
    @Override
    public void run() {
        if (Thread.currentThread().getName().equals("Thread-0")) {
            method1();
        } else {
            method2();
        }
    }
    private void method1() {
        synchronized (lock1) {
            System.out.println("Thread-0 持有 lock1");
            try { Thread.sleep(100); } catch (InterruptedException e) {}
            synchronized (lock2) {
                System.out.println("Thread-0 持有 lock2");
            }
        }
    }
    private void method2() {
        synchronized (lock2) {
            System.out.println("Thread-1 持有 lock2");
            try { Thread.sleep(100); } catch (InterruptedException e) {}
            synchronized (lock1) {
                System.out.println("Thread-1 持有 lock1");
            }
        }
    }
    public static void main(String[] args) {
        DeadlockExample example = new DeadlockExample();
        Thread t1 = new Thread(example, "Thread-0");
        Thread t2 = new Thread(example, "Thread-1");
        t1.start();
        t2.start();
    }
}

6.2 使用 jstack 排查

# 1. 找到 PID
jps -l
# 2. 生成快照
jstack -l 12345 > deadlock.txt
# 3. 查看死锁摘要
grep -A 20 "Found one Java-level deadlock" deadlock.txt

输出类似:

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007f8b5c00a5a8 (object 0x00000000d5f6e3a0, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007f8b5c00b0b0 (object 0x00000000d5f6e3b0, a java.lang.Object),
  which is held by "Thread-1"

7. 注意事项

  • 如果进程占用 CPU 过高,也可用 jstack 查看线程状态,结合 top -H -p <pid> 找到高 CPU 线程 ID 转十六进制后匹配堆栈。
  • 多次生成快照(间隔几秒)有助于对比线程状态变化。
  • 在容器中,可能需要进入容器内部执行 jstack,或使用 docker exec。
  • 若 jstack 不可用(如 JVM 未安装完整 JDK),可使用 kill -3 <pid> 将线程快照输出到标准错误(通常记录在应用日志中)。

通过以上步骤,可以快速定位并解决 Java 应用中的死锁问题。

到此这篇关于Java使用jstack排查死锁(面试考点)的文章就介绍到这了,更多相关Java jstack排查死锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring IOC (DI) 依赖注入的四种方式示例详解

    Spring IOC (DI) 依赖注入的四种方式示例详解

    这篇文章主要介绍了Spring IOC (DI) 依赖注入的四种方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • JAVA中Spring Boot的AOP切面编程是什么,如何使用?(实例代码)

    JAVA中Spring Boot的AOP切面编程是什么,如何使用?(实例代码)

    本文详细介绍了SpringBoot中面向切面编程(AOP)的基本概念、核心术语、配置方法以及应用场景,涵盖了AOP的五种通知类型、切点表达式、动态代理、切面优先级与执行顺序等核心知识点,并通过实战案例展示了AOP在微服务架构中的应用潜力
    2026-01-01
  • 浅谈Mybatis之参数传递的几种姿势

    浅谈Mybatis之参数传递的几种姿势

    在mybatis的日常开发中,mapper接口中定义的参数如何与xml中的参数进行映射呢?本文就详细的介绍一下,感兴趣的可以了解一下
    2021-09-09
  • 一文搞懂Mybatis中Mapper配置文件获取参数的五种方式

    一文搞懂Mybatis中Mapper配置文件获取参数的五种方式

    这篇文章主要介绍了Mybatis中Mapper配置文件获取参数的五种方式,文中通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-03-03
  • Java中Synchronized和Static Synchronized的区别及说明

    Java中Synchronized和Static Synchronized的区别及说明

    这篇文章主要介绍了Java中Synchronized和Static Synchronized的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • SpringMVC上传文件并保存到本地代码实例

    SpringMVC上传文件并保存到本地代码实例

    这篇文章主要介绍了SpringMVC上传文件并保存到本地代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • 实体类或对象序列化时,忽略为空属性的操作

    实体类或对象序列化时,忽略为空属性的操作

    这篇文章主要介绍了实体类或对象序列化时,忽略为空属性的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 详解Java中LinkedStack链栈的实现

    详解Java中LinkedStack链栈的实现

    这篇文章主要为大家详细介绍了Java中LinkedStack链栈的相关知识,文中的示例代码讲解详细,对我们学习Java有一定帮助,需要的可以参考一下
    2022-11-11
  • MyBatis-Plus中的逻辑删除使用详解

    MyBatis-Plus中的逻辑删除使用详解

    开发系统时,有时候在实现功能时,删除操作需要实现逻辑删除就是将数据标记为删除,而并非真的物理删除(非DELETE操作),查询时需要携带状态条件,确保被标记的数据不被查询到。这样做的目的就是避免数据被真正的删除
    2022-12-12
  • java计算两个日期之前的天数实例(排除节假日和周末)

    java计算两个日期之前的天数实例(排除节假日和周末)

    下面小编就为大家带来一篇java计算两个日期之前的天数实例(排除节假日和周末)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07

最新评论