Java線程死鎖是一個經典的多線程問題。由於不一樣的線程都在等待根本不可能被釋放的鎖,從而致使全部的任務都沒法繼續完成。多線程
建立類 DeadLockThread:ide
public class DeadLockThread implements Runnable { private Object lock1 = new Object(); private Object lock2 = new Object(); private String s; public void setS(String s) { this.s = s; } @Override public void run() { if ("a".equalsIgnoreCase(s)) { synchronized (lock1) { System.out.println(Thread.currentThread() + " a 正在執行"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock2) { System.out.println("lock1 -> lock2 死鎖未生效"); } } } if ("b".equalsIgnoreCase(s)) { synchronized (lock2) { System.out.println(Thread.currentThread() + " b 正在執行"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock1) { System.out.println("lock2 -> lock1 死鎖未生效"); } } } } }
建立運行類 Main:工具
public class Main { public static void main(String[] args) throws InterruptedException { DeadLockThread deadLockThread = new DeadLockThread(); deadLockThread.setS("a"); Thread threadA = new Thread(deadLockThread); threadA.start(); Thread.sleep(200); deadLockThread.setS("b"); Thread threadB = new Thread(deadLockThread); threadB.start(); Thread.sleep(200); } }
運行結果以下:性能
1.進入JDK安裝文件夾中的bin目錄,執行jps命令:測試
獲得正在運行着的線程Main的id值是12295。ui
2.在執行 jstack -l 12295 命令,查看結果:this
由此結果可知,程序有死鎖的現象。idea
右鍵測試代碼所在的包,選擇分析包內文件spa
分析結果以下:插件
This method calls Thread.sleep() with a lock held. This may result in very poor performance and scalability, or a deadlock, since other threads may be waiting to acquire the lock. It is a much better idea to call wait() on the lock, which releases the lock and allows other threads to run.
此方法調用thread.sleep(),並保留一個鎖。
這可能會致使性能和可伸縮性很是差,或者出現死鎖,由於其餘線程可能正在等待獲取鎖。
最好對鎖調用wait(),這樣能夠釋放鎖並容許其餘線程運行。
死鎖是程序設計的bug,在設計程序時要避免雙方互相持有對方鎖的狀況。須要說明的是,本實驗使用synchronized嵌套的代碼結構來實現死鎖,其實不使用嵌套的synchronized代碼結構也會出現死鎖,與嵌套不嵌套沒有任何的關係。只要互相等待對方釋放鎖,就有可能出現死鎖。