七、死锁
1、问题引出
class DeadLock {
private final Object LOCK_A = new Object();
private final Object LOCK_B = new Object();
public void methodA() {
synchronized (LOCK_A) {
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName() + "获取锁A,尝试获取锁B");
synchronized (LOCK_B) {
}
}
}
public void methodB() {
synchronized (LOCK_B) {
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName() + "获取锁B,尝试获取锁A");
synchronized (LOCK_A) {
}
}
}
}
public class DeadLockTest {
public static void main(String[] args) {
DeadLock dl = new DeadLock();
new Thread(dl::methodA, "线程A").start();
new Thread(dl::methodB, "线程B").start();
}
}
执行代码,可以看到程序阻塞,无法执行完毕
2、问题原因
多个已经获取到锁的线程,当尝试获取其他线程已持有的锁时,就会发生死锁现象
3、如何排查
使用Java自带的两个命令:jps
和jstack
首先执行命令:jps -l
,获取正在执行的Java程序的进程ID
再执行命令:jstack -l 进程ID
,即可看到以下类似的信息
"线程B" #12 prio=5 os_prio=0 tid=0x000000001657a800 nid=0x65c waiting for monitor entry [0x0000000016d8f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at DeadLock.methodB(DeadLockTest.java:21)
- waiting to lock <0x00000000f57e2568> (a java.lang.Object)
- locked <0x00000000f57e2578> (a java.lang.Object)
at DeadLockTest$$Lambda$2/205797316.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
"线程A" #11 prio=5 os_prio=0 tid=0x0000000016579800 nid=0x4f4 waiting for monitor entry [0x0000000016c8e000]
java.lang.Thread.State: BLOCKED (on object monitor)
at DeadLock.methodA(DeadLockTest.java:11)
- waiting to lock <0x00000000f57e2578> (a java.lang.Object)
- locked <0x00000000f57e2568> (a java.lang.Object)
at DeadLockTest$$Lambda$1/1637070917.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers:
- None
Found one Java-level deadlock:
=============================
"线程B":
waiting to lock monitor 0x0000000002ffde38 (object 0x00000000f57e2568, a java.lang.Object),
which is held by "线程A"
"线程A":
waiting to lock monitor 0x0000000002ffb658 (object 0x00000000f57e2578, a java.lang.Object),
which is held by "线程B"
Java stack information for the threads listed above:
===================================================
"线程B":
at DeadLock.methodB(DeadLockTestjava:21)
- waiting to lock <0x00000000f57e2568> (a java.lang.Object)
- locked <0x00000000f57e2578> (a java.lang.Object)
at DeadLockTest$$Lambda$2/205797316.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
"线程A":
at DeadLock.methodA(DeadLockTestjava:11)
- waiting to lock <0x00000000f57e2578> (a java.lang.Object)
- locked <0x00000000f57e2568> (a java.lang.Object)
at DeadLockTest$$Lambda$1/1637070917.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
清楚地标识出了死锁的位置