面試突擊48:死鎖的排查工具有哪些?
死鎖(Dead Lock)指的是兩個或兩個以上的運算單元(程序、執行緒或協程),都在等待對方釋放資源,但沒有一方提起釋放資源,從而造成了一種阻塞的現象就稱為死鎖。
比如執行緒 1 擁有了鎖 A 的情況下試圖獲取鎖 B,而執行緒 2 又在擁有了鎖 B 的情況下試圖獲取鎖 A,這樣雙方就進入相互阻塞等待的情況,如下圖所示:
死鎖的程式碼實現如下:
import java.util.concurrent.TimeUnit; public class DeadLockTest { public static void main(String[] args) { Object lockA = new Object(); Object lockB = new Object(); // 建立執行緒 1 Thread t1 = new Thread(() -> { // 1.佔有鎖 A synchronized (lockA) { System.out.println("執行緒1:獲得鎖A。"); // 休眠 1s(讓執行緒 2 有時間先佔有鎖 B) try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } // 2.獲取執行緒 2 的鎖 B synchronized (lockB) { System.out.println("執行緒1:獲得鎖B。"); } } }); t1.start(); // 建立執行緒 2 Thread t2 = new Thread(() -> { // 1.佔有鎖 B synchronized (lockB) { System.out.println("執行緒2:獲得鎖B。"); // 休眠 1s(保證執行緒 1 能有充足的時間得到鎖 A) try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } // 2.獲取執行緒 1 的鎖 A synchronized (lockA) { System.out.println("執行緒2:獲得鎖A。"); } } }); t2.start(); } }
以上程式的執行結果如下圖所示:
從上述結果可以看出,執行緒 1 和執行緒 2 都在等待對方釋放鎖,這樣就造成了死鎖問題。
哪死鎖應該如何排查呢?
死鎖的排查工具
排查死鎖總共有 4 種工具:
- jstack
- jconsole
- jvisualvm
- jmc
接下來,我們一一來看。
排查工具 1:jstack
在使用 jstack 之前,先要通過 jps 得到執行程式的程序 ID,使用方法如下:
“jps -l”可以查詢本機所有的 Java 程式,jps(Java Virtual Machine Process Status Tool)是 Java 提供的一個顯示當前所有 Java 程序 pid 的命令,適合在 linux/unix/windows 平臺上簡單檢視當前 Java 程序的一些簡單情況,“-l”用於輸出程序 pid 和執行程式完整路徑名(包名和類名)。
有了程序 ID(PID)之後,我們就可以使用“jstack -l PID”來發現死鎖問題了,如下圖所示:
jstack 用於生成 Java 虛擬機器當前時刻的執行緒快照,“-l”表示長列表(long),列印關於鎖的附加資訊。
PS:可以使用 jstack -help 檢視更多命令使用說明。
排查工具 2:jconsole
使用 jconsole 需要開啟 JDK 的 bin 目錄,找到 jconsole 並雙擊開啟,如下圖所示:
然後選擇要除錯的程式,如下圖所示:
之後點選連線進入,選擇“不安全的連線”進入監控主頁,如下圖所示:
之後切換到“執行緒”模組,點選“檢測死鎖”按鈕,如下圖所示:
之後稍等片刻就會檢測出死鎖的相關資訊,如下圖所示:
排查工具 3:jvisualvm
jvisualvm 也在 JDK 的 bin 目錄中,同樣是雙擊開啟:
稍等幾秒之後,jvisualvm 中就會出現本地的所有 Java 程式,如下圖所示:
雙擊選擇要除錯的程式:
單擊滑鼠進入“執行緒”模組,如下圖所示:
從上圖可以看出,當我們切換到執行緒一欄之後就會直接顯示出死鎖資訊,之後點選“執行緒 Dump”生成死鎖的詳情資訊,如下圖所示:
排查工具 4:jmc
jmc 是 Oracle Java Mission Control 的縮寫,是一個對 Java 程式進行管理、監控、概要分析和故障排查的工具套件。它也是在 JDK 的 bin 目錄中,同樣是雙擊啟動,如下圖所示:
jmc 主頁資訊如下:
之後選中要排查的程式,右鍵“啟動 JMX 控制檯”檢視此程式的詳細內容,如下圖所示:
然後點選“執行緒”,勾中“死鎖檢測”就可以發現死鎖和死鎖的詳情資訊,如下圖所示:
總結
死鎖的排查工具總共有 4 種:jstack、jconsole、jvisualvm、jmc,從易用性和效能方面來考慮,推薦使用 jconsole 或 jvisualvm 來排查死鎖。
是非審之於己,譭譽聽之於人,得失安之於數。
公眾號:Java面試真題解析
面試合集:https://gitee.com/mydb/interview