線程死鎖檢測方法

多條線程以不同的順序搶佔同步資源的時候,就有可能發生死鎖。

如下圖所示,線程1持有鎖對象A而希望獲得鎖對象B;另一方面,線程2持有鎖對象B而希望

獲得鎖對象A。並且這兩個線程的操作是交錯執行的,因此它們會發生死鎖。


當發生的死鎖後,JDK自帶了兩個工具(jstack和JConsole),可以用來監測分析死鎖的發生原因。

jstack工具用於生於生成虛擬機當前時刻的線程快照。線程快照就是當前虛擬機每一條線程正在

執行的方法堆棧的集合,生成快照可以用於定位諸如線程死鎖、死循環等問題。

JConsole是一種可視化監視管理工具。用於連接正在運行的JVM進程,以監控Java 應用程序性

能和跟蹤 Java 中的代碼。

下面以一個死鎖例子來說明如何使用這兩個工具來分析線程死鎖。

死鎖示例代碼如下:

[java] view plain copy
  1. class SynThread implements Runnable{  
  2.       
  3.     int a ,b;  
  4.       
  5.     public SynThread(int a,int b){  
  6.         this.a=a;  
  7.         this.b=b;  
  8.     }  
  9.     @Override  
  10.     public void run() {  
  11.         synchronized (Integer.valueOf(a)) {//必須用valueOf()方法  
  12.             synchronized (Integer.valueOf(b)) {  
  13.                 System.err.println("a+b=="+(a+b));  
  14.             }  
  15.         }  
  16.     }  
  17.       
  18. }  
  19.   
  20. public class entry {  
  21.   
  22.     public static void main(String[] args) {  
  23.           
  24.         //循環主要是爲了加大死鎖概率  
  25.         for(int i=0;i<100;i++){  
  26.             new Thread(new SynThread(1,2)).start();  
  27.             new Thread(new SynThread(2,1)).start();  
  28.         }  
  29.     }  
  30. }  

說明:以上代碼有可能發生死鎖,原因是Integer.valueOf()方法作了緩存優化,對[-128,127]之間

的數字會被緩存。也就是說,循環代碼中一共只創建了兩個不同的對象。假設在兩個synchronized

塊之間發生了線程切換,那就有可能造成,線程A等待被線程B持有Integer.valueOf(1)對象,線程B

等待被線程A持有Integer.valueOf(2)對象,結果出現了死鎖。(可能需要多次執行直到程序出現

阻塞現象)


JDK源代碼Integer.java類對valueOf()方法的優化細節如下

[java] view plain copy
  1. public static Integer valueOf(int i) {  
  2.     if(i >= -128 && i <= IntegerCache.high)  
  3.         return IntegerCache.cache[i + 128];  
  4.     else  
  5.         return new Integer(i);  
  6. }  

  • 使用jstack工具導出線程堆棧信息(以Windows環境爲例)

1.找到運行當前程序的JVM的進程id,命令及結果如下



2.運行jstack命令,並將結果信息導出來


3.使用文本編輯器打開剛導出的文本,只要查看最後關於死鎖的堆棧信息即可


4.直接從堆棧信息不能直觀得到結論,沒關係,我們可以畫圖理清線程間的調度情況

出現閉合環路,發生死鎖


  • 使用JConsole可視化工具檢測死鎖

1.直接執行JConsole工具(在jdk/bin目錄下),選擇目標JVM進程,然後點擊連接


2.切換到“線程”標籤頁,點擊“檢測死鎖”按鈕



3.選擇不同的線程,可以查看其資源調度信息,採用類似的方法分析,可以得出與

採用jstack分析一樣的結論



發佈了103 篇原創文章 · 獲贊 71 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章