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排查死锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MybatisPlus代码生成器含XML文件详解

    MybatisPlus代码生成器含XML文件详解

    这篇文章主要介绍了MybatisPlus代码生成器含XML文件详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • 超详细讲解SpringCloud Commons公共抽象的用法

    超详细讲解SpringCloud Commons公共抽象的用法

    这篇文章主要介绍了超详细讲解SpringCloud Commons公共抽象的用法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Java图片批量压缩像素的实现方法

    Java图片批量压缩像素的实现方法

    我们开发中经常会遇到原图清晰度高,考虑到效率问题,我们不可能拿原图进行显示,服务端一般都要对图片进行压缩处理,然后发送给客户端显示,这篇文章主要给大家介绍了关于Java图片批量压缩像素的实现方法,需要的朋友可以参考下
    2021-12-12
  • mybatis trim标签的使用详解

    mybatis trim标签的使用详解

    这篇文章主要介绍了mybatis trim标签的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Java实现Redisson分布式锁的10大陷阱与避坑指南

    Java实现Redisson分布式锁的10大陷阱与避坑指南

    本文介绍了Redisson分布式锁的基础用法与高级特性,包括基本锁操作、公平锁、读写锁、联锁和红锁等实现方式,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2026-04-04
  • JAVA中HTTP基本认证(Basic Authentication)实现

    JAVA中HTTP基本认证(Basic Authentication)实现

    HTTP 基本认证是一种简单的认证方法,本文主要介绍了JAVA中HTTP基本认证(Basic Authentication),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07
  • SpringBoot默认日志logback输出格式配置

    SpringBoot默认日志logback输出格式配置

    Springboot内置使用了commons-logging日志门面,并内置一个logback日志实现,默认输出INFO级别,可以在application配置文件中修改logback的默认配置,下面就来介绍一下,感兴趣的可以了解一下
    2025-09-09
  • SpringBoot使用itext填充pdf表单及导出pdf的流程

    SpringBoot使用itext填充pdf表单及导出pdf的流程

    由于最近开发的项目需要用到打印单据,就在网上找了一下方案,反反复复,都没有找到合适的,借鉴了网上资源,使用itext5、itext7的工具包,所以本文介绍了SpringBoot使用itext填充pdf表单及导出pdf的流程,需要的朋友可以参考下
    2024-09-09
  • 浅谈Spring5 响应式编程

    浅谈Spring5 响应式编程

    本篇文章主要介绍了浅谈Spring5 响应式编程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • JDK8并行流及串行流区别原理详解

    JDK8并行流及串行流区别原理详解

    这篇文章主要介绍了JDK8并行流及串行流区别原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07

最新评论