建立基本的死鎖系統

當兩個競爭動作等待另一個完成時發生死鎖,因此兩者都沒有。在 java 中,每個物件都有一個鎖。為了避免單個物件上的多個執行緒進行併發修改,我們可以使用 synchronized 關鍵字,但一切都需要付出代價。錯誤地使用 synchronized 關鍵字會導致被稱為死鎖系統的卡住系統。

考慮在 1 個例項上有 2 個執行緒工作,讓我們將執行緒呼叫為 First 和 Second,並且假設我們有 2 個資源 R1 和 R2。首先獲得 R1 並且還需要 R2 完成,而 Second 獲得 R2 並需要 R1 完成。

所以說在時間 t = 0,

首先是 R1,第二個是 R2。現在第一個是等待 R2 而第二個等待 R1。這種等待是無限期的,這會導致僵局。

public class Example2 {
    
    public static void main(String[] args) throws InterruptedException {
        final DeadLock dl = new DeadLock();
        Thread t1 = new Thread(new Runnable() {
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                dl.methodA();
            }
        });
   
        Thread t2 = new Thread(new Runnable() {
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    dl.method2();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
        t1.setName("First");
        t2.setName("Second");
        t1.start();
        t2.start();
    }
}

class DeadLock {
    
    Object mLock1 = new Object();
    Object mLock2 = new Object();
    

    public void methodA() {
        System.out.println("methodA wait for mLock1  " + Thread.currentThread().getName());
        synchronized (mLock1) {
            System.out.println("methodA mLock1 acquired   " + Thread.currentThread().getName());
            try {
                Thread.sleep(100);
                method2();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    public void method2() throws InterruptedException {
        System.out.println("method2 wait for mLock2  " + Thread.currentThread().getName());
        synchronized (mLock2) {
            System.out.println("method2  mLock2 acquired   " + Thread.currentThread().getName());
            Thread.sleep(100);
            method3();
        }
    }
    public void method3() throws InterruptedException {
        System.out.println("method3  mLock1  "+ Thread.currentThread().getName());
        synchronized (mLock1) {
            System.out.println("method3   mLock1 acquired  " + Thread.currentThread().getName());
        }
    }
}

該計劃的輸出:

methodA wait for mLock1  First
method2 wait for mLock2  Second
method2  mLock2 acquired   Second
methodA mLock1 acquired   First
method3  mLock1  Second
method2 wait for mLock2  First