死鎖產生的四個必要條件。java
1>互斥使用,即當資源被一個線程使用(佔有)時,別的線程不能使用
ide
2>不可搶佔,資源請求者不能強制從資源佔有者手中奪取資源,資源只能由資源佔有者主動釋放。
線程
3>請求和保持,即當資源請求者在請求其餘的資源的同時保持對原有資源的戰友。
code
4>循環等待,即存在一個等待隊列:P1佔有P2的資源,P2佔有P3的資源,P3佔有P1的資源。這樣就造成了一個等待環路。
隊列
當上述四個條件都成立的時候,便造成死鎖。固然,死鎖的狀況下若是打破上述任何一個條件,即可讓死鎖消失。下面用java代碼來模擬一下死鎖的產生。資源
package com.lu.simulation; /** * 該類存放兩個資源等待被使用 * @author lu * */ public class Resource { public static Object o1 = new Object(); public static Object o2 = new Object(); } package com.lu.simulation; /** * 線程啓動調用run(),run()調用fun()方法 * @author lu * */ public class DeadThread1 implements Runnable { @Override public void run() { fun(); } //fun()方法首先佔用o1資源,而後休眠1秒,讓給其餘線程執行。 //而後請求o2資源 public void fun() { synchronized (Resource.o1) { try { Thread.sleep(1000); } catch (InterruptedException e) { } synchronized (Resource.o2) { System.out.println("DeadThread1裏的fun()被執行"); } } } } package com.lu.simulation; /** * 線程啓動調用run(),run()調用fun()方法 * @author lu * */ public class DeadThread2 implements Runnable { @Override public void run() { fun(); } //fun()方法首先佔用o2資源,而後休眠1秒,讓給其餘線程執行。 //而後請求o1資源 public void fun() { synchronized (Resource.o2) { try { Thread.sleep(1000); } catch (InterruptedException e) { } synchronized (Resource.o1) { System.out.println("DeadThread1裏的fun()被執行"); } } } } package com.lu.simulation; /** * 客戶端 * @author lu * */ public class Client { public static void main(String[] args) { DeadThread1 dt1 = new DeadThread1(); DeadThread2 dt2 = new DeadThread2(); Thread t1 = new Thread(dt1); Thread t2 = new Thread(dt2); //啓動兩個線程 t1.start(); t2.start(); } }
當啓動線程t1後,執行t1的fun方法,佔用o1資源,而後t1休眠確保可以讓t2來執行。t2執行fun()方法,佔有o2資源。此時就造成了死鎖產生的第四個必要條件。即線程t1佔有了t2所需的資源,t2佔有了t1所需的資源,雙方都不釋放,即造成死鎖。io