每日學習20170711--JAVA死鎖排查利器

什麼是死鎖

死鎖:兩個或多個動作一直在等待其他動作的完成而使得所有動作都始終處於阻塞的狀態。
開發階段檢測死鎖很困難;測試階段也很困難-死鎖通常發生在負載嚴重的情況下。解除死鎖往往需要重啓程序。
儘管有些靜態分析庫可以幫助我們發現可能出現的死鎖,但還是有必須在運行時檢測到死鎖,得到信息,以便我們解決問題或重啓。

產生死鎖的例子

如圖:
這裏寫圖片描述

這裏寫圖片描述

利用JConsole排查死鎖

JConsole是一個基於JMX的GUI工具,用於連接正在運行的JVM,不過此JVM需要使用可管理的模式啓動。
通過JConsole可以查看當前所有線程所處的狀態,如圖:
這裏寫圖片描述

這裏寫圖片描述

利用Jstack排查死鎖

jstack用於生成java虛擬機當前時刻的線程快照。線程快照是當前java虛擬機內每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等。
線程出現停頓的時候通過jstack來查看各個線程的調用堆棧,就可以知道沒有響應的線程到底在後臺做什麼事情,或者等待什麼資源。
通過Jstack命令 Jstack -l 進程號 查看死鎖,如圖:
這裏寫圖片描述

利用ThreadMXBean排查死鎖

前面所介紹的都是利用程序外部的JVM監控管理工具進行死鎖排查,那麼如果希望實現代碼中自動發現死鎖並作出響應(例如重啓服務等)應當怎麼做呢?我們可以利用ThreadMXBean。
Java 5引入了ThreadMXBean接口,它提供了多種監視線程的方法。我建議您瞭解所有這些方法,因爲當您沒使用外部工具時,它們會爲您提供很多有用的操作以便您監測程序性能。
重要方法:findDeadlockedThreads(Java 6); findMonitorDeadlockedThreads (java 5)。(二者的區別的是,findDeadlockedThreads還可以檢測到owner locks(java.util.concurrent)引起的死鎖,而findMonitorDeadlockedThreads只能檢測monitor locks(例如,同步塊)。)

  • 首先編寫一個檢測死鎖的類,需要用到調度接口每隔一段時間執行一次:
    這裏寫圖片描述
  • 編寫一個處理死鎖的類,這裏只做輸出:
    這裏寫圖片描述
  • 修改main方法:
    這裏寫圖片描述
    執行結果如圖:
    這裏寫圖片描述
    通過結果能夠很好的看出每個線程等待哪個鎖,這個鎖被哪個線程持有。

在這個接口的註釋上有這麼兩行:
這裏寫圖片描述
說明這個方法對系統的開銷還是比較大的,所以對於調度的頻率需要根據具體情況慎重考慮。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章