關(guān)于java的死鎖可能網(wǎng)上一大堆的代碼,作為初學(xué)者我覺得還是很有必要練習(xí)下敢订,親自實現(xiàn)王污,并分析其死鎖的原理。
死鎖的原因:
因為兩個或者多個進程互相需要對方手里的鎖而進入了一種互相等待的狀態(tài)楚午。代碼都是順序執(zhí)行的昭齐,所以不能倒退,也就沒有辦法交出手里的鎖矾柜,這是一個大的前提阱驾。
如何形成死鎖:
舉個兩個進程死鎖的例子。首先把沼,死鎖很重要的另一個前提就是鎖的唯一性啊易,我們都知道同步代碼塊需要傳遞一個對象吁伺,也就是我們說的鎖饮睬。兩個進程的死鎖需要兩把鎖,此時就須要保證這兩把鎖都是唯一性篮奄,也就需要兩把鎖都是靜態(tài)的對象捆愁,就像這樣:
class LockTemp {
static final LockTemp l = new LockTemp ();
}
然后構(gòu)造兩個嵌套的同步代碼塊,如下代碼所示:
synchronized (LockA.lock) {
System.out.println("進入外層同步代碼塊");
synchronized (LockB.lock) {
System.out.println("進入內(nèi)層同步代碼塊");
}
}
兩個代碼塊構(gòu)造完成后窟却,需要讓一個t1進程進入A嵌套代碼塊的外層昼丑,另一個t2進程進入B嵌套代碼塊的外層,此時t1需要的另一鎖在t2手上夸赫,t2需要的另一把鎖在t1手上菩帝,所以進入了一種互相等待的狀態(tài),而這種等待的狀態(tài)是沒有辦法結(jié)束的,所以程序進入了死鎖狀態(tài)呼奢。
完整的code:
package thread;
/*
* java多線程死鎖的練習(xí)
*/
public class LockDemo {
public static void main(String[] args) {
// 來兩個dead對象宜雀,一個為true,一個為false
Dead d1 = new Dead(true);
Dead d2 = new Dead(false);
// 創(chuàng)建兩個進程對象并start
Thread t1 = new Thread(d1);
Thread t2 = new Thread(d2);
t1.start();
t2.start();
}
}
// 先來兩把鎖
class LockA {
static final LockA l = new LockA();
}
class LockB {
static final LockB l = new LockB();
}
// 實現(xiàn)死鎖的類
class Dead implements Runnable {
// 定義一個私有的boolean變量握础,來決定線程進入同步代碼的方向
private boolean flag;
public Dead(boolean flag) {
this.flag = flag;
}
public void run() {
while (true) {
if (flag == true) {
synchronized (LockA.l) {
System.out.println("if...A");
synchronized (LockB.l) {
System.out.println("if...B");
}
}
} else {
synchronized (LockB.l) {
System.out.println("else...B");
synchronized (LockA.l) {
System.out.println("else...A");
}
}
}
}
}
}