死鎖發生:兩個或多個線程之間,互相持有對方需要的鎖,而永久處於阻塞狀態
一、手寫死鎖代碼:
public class DeadLockSample extends Thread { private String first; private String second; public DeadLockSample(String name, String first, String second) { super(name); this.first = first; this.second = second; } @Override public void run() { synchronized (first) { System.out.println(this.getName() + " obtained:" + first); try { TimeUnit.SECONDS.sleep(1); synchronized (second){ System.out.println(this.getName() + " obtained:" + second); } } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException{ String lockA = "lockA"; String lockB = "lockB"; DeadLockSample deadLockSample1 = new DeadLockSample("thread1",lockA,lockB); DeadLockSample deadLockSample2 = new DeadLockSample("thread2",lockB,lockA); deadLockSample1.start(); deadLockSample2.start(); deadLockSample1.join(); deadLockSample2.join(); } }
二、死鎖產生的四個條件:
互斥:共享資源X和Y只能被一個線程占用
占有且等待:線程T1已經獲取共享資源X,在等待共享資源Y的時候,不釋放共享資源X
不可搶占:其他線程不能強行搶占線程T1占有的資源
循環等待:線程T1等待線程T2占有的資源,線程T2等待線程T1占有的資源,這就是循環等待。
三、死鎖定位:
jps -l
jstack pid
Found one Java-level deadlock: ============================= "thread2": waiting to lock monitor 0x00007fa34c016148 (object 0x00000007957fc7d0, a java.lang.String), which is held by "thread1" "thread1": waiting to lock monitor 0x00007fa34c016358 (object 0x00000007957fc808, a java.lang.String), which is held by "thread2" Java stack information for the threads listed above: =================================================== "thread2": at com.example.demo.javaLession.lession18.DeadLockSample.run(DeadLockSample.java:41) - waiting to lock <0x00000007957fc7d0> (a java.lang.String) - locked <0x00000007957fc808> (a java.lang.String) "thread1": at com.example.demo.javaLession.lession18.DeadLockSample.run(DeadLockSample.java:41) - waiting to lock <0x00000007957fc808> (a java.lang.String) - locked <0x00000007957fc7d0> (a java.lang.String) Found 1 deadlock.
四、預防死鎖:
破壞占有且等待條件:保證一次申請所有的資源。
破壞不可搶占條件:synchronized無法做到,synchronized申請不到資源直接進入阻塞狀態。
java.util.concurrent Lock可以解決此問題
破壞循環等待條件:需要對資源進行排序,然后按序申請資源
五、修復死鎖
發生死鎖無法在線解決,必須重啟,修正程序本身的問題