Java多執行緒2.1.多執行緒之死鎖
阿新 • • 發佈:2018-12-10
多執行緒之死鎖
1、鎖物件Lock
雖然我們可以理解同步程式碼塊和同步方法的鎖物件問題,但是我們並沒有直接看到在哪裡加上了鎖,在哪裡釋放了鎖。
為了更清晰的表達如何加鎖和釋放鎖,JDK5以後提供了一個新的鎖物件Lock。
- Lock:是一個介面
- void lock()
- void unlock()
- ReentrantLock:Lock介面的一個具體實現類
2、同步弊端:
- 效率低
- 如果出現了同步巢狀,就容易產生死鎖問題
3、死鎖問題及其程式碼演示:
- 是指兩個或者兩個以上的執行緒在執行的過程中,因爭奪資源產生的一種互相等待的現象
- 同步程式碼塊的巢狀案例
(1)建立執行緒類
package cn.itcast_02; public class DieLock extends Thread { private boolean flag; public DieLock(boolean flag) { this.flag = flag; } @Override public void run() { if (flag) { synchronized (MyLock.objA) { System.out.println("if objA"); synchronized (MyLock.objB) { System.out.println("if objB"); } } } else { synchronized (MyLock.objB) { System.out.println("else objB"); synchronized (MyLock.objA) { System.out.println("else objA"); } } } } }
(2)建立鎖
package cn.itcast_02;
public class MyLock {
// 建立兩把鎖物件
public static final Object objA = new Object();
public static final Object objB = new Object();
}
(3)測試執行緒類
package cn.itcast_02; /* * 同步的弊端: * A:效率低 * B:容易產生死鎖 * 死鎖: * 兩個或兩個以上的執行緒在爭奪資源的過程中,發生的一種相互等待的現象。 * 舉例: * 中國人,美國人吃飯案例。 * 正常情況: * 中國人:筷子兩支 * 美國人:刀和叉 * 現在: * 中國人:筷子1支,刀一把 * 美國人:筷子1支,叉一把 */ public class DieLockDemo { public static void main(String[] args) { DieLock dl1 = new DieLock(true); DieLock dl2 = new DieLock(false); dl1.start(); dl2.start(); } }
(4)兩個執行緒使用各自的鎖,出現了問題:
- 執行緒dl1使用鎖A輸出一句話“if objA”,然後被執行緒dl2搶去了CPU資源而被迫阻塞;
- 此時執行緒dl2使用鎖B輸出一句話“else objB”,然後又被執行緒dl1搶去了CPU資源而被迫阻塞;
- 這時,執行緒dl1想繼續執行下一句話,但是需要鎖B,而鎖B這時候被執行緒dl2佔用著,所以又被迫阻塞;
- 這時,如果執行緒dl2又搶到了CPU資源想繼續向下執行的話,但是需要正在被執行緒dl1佔用的鎖A,所以又被迫阻塞;
- 依次產生死鎖問題。