# 如何寫出一個 Java 死鎖程序以及分析jstack
## 一、什么是死鎖
死鎖(Deadlock)是指兩個或多個線程在執行過程中,因爭奪資源而造成的一種互相等待的現象。當多個線程同時被阻塞,它們中的一個或者全部都在等待某個資源被釋放,導致這些線程無限期地阻塞下去。
死鎖的四個必要條件:
1. **互斥條件**:資源一次只能由一個線程占用
2. **請求與保持條件**:線程持有至少一個資源,并等待獲取其他資源
3. **不剝奪條件**:已分配給線程的資源不能被其他線程強行奪取
4. **循環等待條件**:存在一個線程的循環等待鏈
## 二、編寫Java死鎖程序
下面是一個簡單的Java死鎖示例程序:
```java
public class DeadlockDemo {
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
public static void main(String[] args) {
Thread threadA = new Thread(() -> {
synchronized (lock1) {
System.out.println("ThreadA holding lock1...");
try {
Thread.sleep(100); // 模擬業務處理
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadA waiting for lock2...");
synchronized (lock2) {
System.out.println("ThreadA holding lock1 and lock2...");
}
}
});
Thread threadB = new Thread(() -> {
synchronized (lock2) {
System.out.println("ThreadB holding lock2...");
try {
Thread.sleep(100); // 模擬業務處理
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadB waiting for lock1...");
synchronized (lock1) {
System.out.println("ThreadB holding lock2 and lock1...");
}
}
});
threadA.start();
threadB.start();
}
}
運行上述程序后,控制臺輸出可能會卡在類似以下狀態:
ThreadA holding lock1...
ThreadB holding lock2...
ThreadA waiting for lock2...
ThreadB waiting for lock1...
程序不會終止,因為兩個線程互相持有對方需要的鎖,形成了死鎖。
jstack是JDK自帶的一個命令行工具,用于生成Java虛擬機當前時刻的線程快照(thread dump)。
首先使用jps
命令查找Java進程的PID:
jps -l
使用jstack命令生成線程轉儲:
jstack -l <PID> > deadlock.log
打開生成的deadlock.log文件,搜索”deadlock”或”Found one Java-level deadlock”,可以看到類似以下內容:
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007f8b381062b8 (object 0x000000076ab270c0, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x00007f8b38107318 (object 0x000000076ab270d0, a java.lang.Object),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at DeadlockDemo.lambda$main$1(DeadlockDemo.java:28)
- waiting to lock <0x000000076ab270c0> (a java.lang.Object)
- locked <0x000000076ab270d0> (a java.lang.Object)
"Thread-0":
at DeadlockDemo.lambda$main$0(DeadlockDemo.java:14)
- waiting to lock <0x000000076ab270d0> (a java.lang.Object)
- locked <0x000000076ab270c0> (a java.lang.Object)
tryLock()
)ConcurrentHashMap
、CountDownLatch
等通過理解死鎖原理、編寫示例程序和使用jstack工具分析,我們可以更好地識別和解決Java程序中的死鎖問題。 “`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。