使用jstack定位程序许久没有反应死锁问题

简介: 使用jstack定位程序许久没有反应死锁问题

引言

这个情况现象的程序运行的时候迟迟没有输出,我们可以怀疑的死锁的问题,但是怎么去定位这个问题呢,我们还是借助jstack来做。

jstack 163746

这个查看没有太复杂的流程,直接查看堆栈信息最后的一部分就ok

Found one Java-level deadlock:
=============================
"Thread_02":
  waiting to lock monitor 0x00002b578c002178 (object 0x000000058015e5c0, a O1),
  which is held by "Thread_01"
"Thread_01":
  waiting to lock monitor 0x00002b578c006218 (object 0x000000058015f148, a O2),
  which is held by "Thread_02"

Java stack information for the threads listed above:
===================================================
"Thread_02":
        at Demo1_3.lambda$main$1(Demo1_3.java:28)
        - waiting to lock <0x000000058015e5c0> (a O1)
        - locked <0x000000058015f148> (a O2)
        at Demo1_3$$Lambda$2/1418481495.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)
"Thread_01":
        at Demo1_3.lambda$main$0(Demo1_3.java:17)
        - waiting to lock <0x000000058015f148> (a O2)
        - locked <0x000000058015e5c0> (a O1)
        at Demo1_3$$Lambda$1/834600351.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

信息会很明确告诉有一个死锁,并且指明了代码行17行和28行,定位到这里就方便了,我们拿出源代码看看:

class O1{}
class O2{}
public class Demo1_3 {
    static O1 o1=new O1();
    static  O2 o2=new O2();
    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            synchronized (o1){
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                synchronized (o2){
                    System.out.println("我是线程1,我获得了o1和o2");
                }
            }
        },"Thread_01").start();
        Thread.sleep(1000);
        
        new Thread(()->{
            synchronized (o2){
                synchronized (o1){
                    System.out.println("我是线程2,我获得了o1和o2");
                }
            }
        },"Thread_02").start();
    }
}

可以看到,线程1和2分别取锁定o1和o2,线程1在持有了o1的同时又准备去锁住o2,而线程2则先持有o2再去锁定o1,双方都没有释放,进而死锁了。

目录
相关文章
|
Java 开发者
使用jstack结合代码来演示【Java线程状态】
Java线程状态一直是让工程师容易迷惑的知识点,我觉得原因有二:一是线程的概念较为抽象,其状态转换的条件和时间点不容易理解;二是线程状态和进程状态不是完全对应的,且线程的状态词汇容易让人误解。下面我们通过jstack结合代码来探究一下Java线程状态相关的关键知识点。
304 0
|
2月前
|
小程序 JavaScript Java
【Java】服务CPU占用率100%,教你用jstack排查定位
本文详细讲解如何使用jstack排查定位CPU高占用问题。首先介绍jstack的基本概念:它是诊断Java应用程序线程问题的工具,能生成线程堆栈快照,帮助找出程序中的瓶颈。接着,文章通过具体步骤演示如何使用`top`命令找到高CPU占用的Java进程及线程,再结合`jstack`命令获取堆栈信息并进行分析,最终定位问题代码。
128 1
【Java】服务CPU占用率100%,教你用jstack排查定位
|
3月前
|
Java
Jstack 查看线程状态及定位占用 cpu 较高的 java 线程
Jstack 查看线程状态及定位占用 cpu 较高的 java 线程
203 2
|
3月前
|
Java
JVM内存问题之jstack命令查看JVM线程快照如何解决
JVM内存问题之jstack命令查看JVM线程快照如何解决
使用 jconsole 命令观察线程
当我们使用多线程编程时,我们可以使用 jconsole 来观察线程的状况。下面我将带领大家如何找到 jconsole 命令
使用 jconsole 命令观察线程
|
Java API
【JAVA并发编程专题】死锁的修复和定位
【JAVA并发编程专题】死锁的修复和定位
|
人工智能 Java 大数据
jstack命令:教你如何排查多线程问题
image 这是之前的一个死锁案例: 一个多线程死锁案例,如何避免及解决死锁问题? 如程序中发生这样的死锁问题该如何排查呢?我们可以使用java自带的jstack命令进行排查。
3153 0
|
Java 中间件 Unix
JVM:如何分析线程堆栈
英文原文:JVM: How to analyze Thread Dump 在这篇文章里我将教会你如何分析JVM的线程堆栈以及如何从堆栈信息中找出问题的根因。在我看来线程堆栈分析技术是Java EE产品支持工程师所必须掌握的一门技术。
1694 0
|
Arthas 监控 网络协议
一次由于OOM导致锁没有释放的定位流程(结合Arthas)
一次由于OOM导致锁没有释放的定位流程(结合Arthas)
使用jstack检测Java应用的死锁(deadlock)状态
使用jstack检测Java应用的死锁(deadlock)状态
161 0
使用jstack检测Java应用的死锁(deadlock)状态