java线程死锁分析方法
程序员文章站
2022-04-18 14:37:28
...
1、jps命令查找所进程id:
admindeMacBook-Pro-49:~ chendu$ jps
19265 Launcher
28819 Launcher
29235 Jps
28820 Concurrent
1596
2、jstack查看 Java 进程内当前时刻的线程快照,也就是每条线程正在执行的方法栈情况,用于定位线程停顿、死锁等长时间等待的问题。
jstack的帮助文档:
Usage:
jstack [-l] <pid>
(to connect to running process)
jstack -F [-m] [-l] <pid>
(to connect to a hung process)
jstack [-m] [-l] <executable> <core>
(to connect to a core file)
jstack [-m] [-l] [[email protected]]<remote server IP or hostname>
(to connect to a remote debug server)
Options:
-F to force a thread dump. Use when jstack <pid> does not respond (process is hung)
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
-h or -help to print this help message
admindeMacBook-Pro-49:~ chendu$ jstack -l 28820
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007fe75300b8b8 (object 0x000000076acac7b8, a java.lang.String),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x00007fe75300cca8 (object 0x000000076acac7e8, a java.lang.String),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at com.sample.Concurrent$2.run(Concurrent.java:34)
- waiting to lock <0x000000076acac7b8> (a java.lang.String)
- locked <0x000000076acac7e8> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
"Thread-0":
at com.sample.Concurrent$1.run(Concurrent.java:20)
- waiting to lock <0x000000076acac7e8> (a java.lang.String)
- locked <0x000000076acac7b8> (a java.lang.String)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
可以发现Thread-0的waiting to lock对象等于Thread-1的locked对象,同时Thread-1的waiting to lock对象等于Thread-0的locked对象,两个线程由于互相持有对方需要的锁而发生的阻塞现象;
例程:
package com.sample;
public class Concurrent {
private static String resource_a = "A";
private static String resource_b = "B";
public static void main(String[] args) {
deadLock();
}
public static void deadLock() {
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
synchronized (resource_a) {
System.out.println("get resource a");
try {
Thread.sleep(3000);
synchronized (resource_b) {
System.out.println("get resource b");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
synchronized (resource_b) {
System.out.println("get resource b");
synchronized (resource_a) {
System.out.println("get resource a");
}
}
}
});
threadA.start();
threadB.start();
}
}