如何查看是否有Java線程死鎖?下面介紹兩種方法。html
一.Jconsole
Jconsole是JDK自帶的圖形化界面工具,使用JDK給咱們的的工具JConsole,能夠經過打開cmd而後輸入jconsole打開。java
鏈接到須要查看的進程。ide
打開線程選項卡,而後點擊左下角的「檢測死鎖」 。工具
jconsole就會給咱們檢測出該線程中形成死鎖的線程,點擊選中便可查看詳情:this
從上圖中咱們能夠看出:spa
在線程Thread-1中,從狀態能夠看出,它想申請java.lang.Object@35b4e829這個資源,可是這個資源已經被Thread-0擁有了,因此就堵塞了。命令行
在線程Thread-0中,從狀態能夠看出,它想申請java.lang.Object@2db8dc9這個資源,可是這個資源已經被Thread-1擁有了,因此就堵塞了。線程
Thread-1一直等待java.lang.Object@35b4e829資源,而Thread–0一直等待java.lang.Object@2db8dc9資源,因而這兩個線程就這麼僵持了下去,形成了死鎖。3d
二.Jstackcode
Jstack是JDK自帶的命令行工具,主要用於線程Dump分析。
1.咱們先用Jps來查看java進程id(或者Linux的ps命令)
2.看一下jstack的使用
3.jstack輸出線程dump信息到文件
用比較工程查看帶-l和不帶-l的區別以下:
4.查看dump文件,而後進行分析
其中有一行是at DeadThread.run(DeadThread.java:37),說明Thread-1實在DeadThread類的37行處發生死鎖,其中at DeadThread.run(DeadThread.java:21),說明Thread-0是在DeadThread類的21行處發生死鎖。詳細的jstack dump文件分析請參看:http://www.cnblogs.com/flyingeagle/articles/6853454.html。
從而定位到死鎖發生的緣由,及具體位置:Thread-0得到了鎖lock1,接下來指望得到鎖lock2,(第20行),可是此時Thread-1得到了鎖lock2,接下來指望得到鎖lock2,(第37行),於是發生了死鎖。
附實例DeadThread.java代碼:
public class DeadThread implements Runnable { public String username; public Object lock1 = new Object(); public Object lock2 = new Object(); @Override public void run() { // TODO Auto-generated method stub if (username.equals("a")) { synchronized (lock1) { try { System.out.println("username = " + username); System.out.println(Thread.currentThread().getName()); Thread.sleep(3000); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } synchronized (lock2) { System.out.println("按lock1->lock2的順序執行代碼"); } } } if (username.equals("b")) { synchronized (lock2) { try { System.out.println("username = " + username); System.out.println(Thread.currentThread().getName()); Thread.sleep(3000); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } synchronized (lock1) { System.out.println("按lock2->lock1順序執行代碼"); } } } } public void setFlag(String username) { this.username = username; } public static void main(String[] args) { DeadThread dt1 = new DeadThread(); dt1.setFlag("a"); Thread t1 = new Thread(dt1); t1.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } dt1.setFlag("b"); Thread t2 = new Thread(dt1); t2.start(); } }