當一個線程永遠地持有一個鎖,並且其他線程都嘗試去獲得這個鎖時,那麼它們將永遠被阻塞,這個我們都知道。如果線程A持有鎖L並且想獲得鎖M,線程B持有鎖M並且想獲得鎖L,那麼這兩個線程將永遠等待下去,這種情況就是最簡單的死鎖形式。
在數據庫系統的設計中考慮了監測死鎖以及從死鎖中恢復,數據庫如果監測到了一組事務發生了死鎖時,將選擇一個犧牲者並放棄這個事務。Java虛擬機解決死鎖問題方面並沒有數據庫這麼強大,當一組Java線程發生死鎖時,這兩個線程就永遠不能再使用了,並且由於兩個線程分別持有了兩個鎖,那麼這兩段同步代碼/代碼塊也無法再運行了—-除非終止並重啓應用。
死鎖是設計的BUG,問題比較隱晦。不過死鎖造成的影響很少會立即顯現出來,一個類可能發生死鎖,並不意味着每次都會發生死鎖,這只是表示有可能。當死鎖出現時,往往是在最糟糕的情況—-高負載的情況下。
死鎖的例子 :
class DeadThread implements Runnable
{
private Boolean flag;
public DeadThread(boolean flag)
{
this.flag = flag;
}
@Override
public void run()
{
if(flag)
{
synchronized (lockObject.locka)
{
System.out.println("if locka");
synchronized (lockObject.lockb)
{
System.out.println("if locka");
}
}
}
else
{
synchronized (lockObject.lockb)
{
System.out.println("else lockb");
synchronized (lockObject.locka)
{
System.out.println("else locka");
}
}
}
}
}
//提供所的類文件
class lockObject
{
static Object locka = new Object();
static Object lockb = new Object();
}
//main 函數
public static void main(String[] args)
{
Thread t1 = new Thread(new DeadThread(true));
Thread t2 = new Thread(new DeadThread(false));
t1.start();
t2.start();
}
輸出結果 :