關(guān)于多線程的一些知識(shí)點(diǎn)(三)——死鎖

老規(guī)矩,先看例子

public class DeadLock {
    public static void main(String[] args) {
        Runnable r1 = new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                synchronized ("A") {
                    System.out.println("A線程持有了A鎖,等待B鎖");
                    synchronized ("B") {
                        System.out.println("A線程持有了A鎖和B鎖");
                    }
                }
            }
        };
        
        Runnable r2 = new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                synchronized ("B") {
                    System.out.println("B線程持有了B鎖,等待A鎖");
                    synchronized ("A") {
                        System.out.println("B線程持有了A鎖和B鎖");
                    }
                }
            }
        };
        
        Thread threadA = new Thread(r1);
        Thread threadB = new Thread(r2);
        threadA.start();
        threadB.start();
    }
}
image.png

我們發(fā)現(xiàn)程序沒有停止,因?yàn)閠hreadA一直在等待B鎖,B鎖卻被threadB搶走了,這時(shí)候threadA還沒有執(zhí)行完并不釋放A鎖,同理threadB在等待A鎖,兩個(gè)人就這樣一直等下去,形成了死鎖。

死鎖:多個(gè)線程互相持有對(duì)方需要的鎖對(duì)象,而不釋放自己的鎖。

解決

public class DeadLock {
    //wait()等待,是Object中的方法,當(dāng)前線程釋放自己的所標(biāo)記,讓出CPU資源,使當(dāng)前線程進(jìn)入等待隊(duì)列
    //notify()通知,是Object中的方法,喚醒等待隊(duì)列中的一個(gè)線程,使這個(gè)線程進(jìn)入鎖池。
    //notifyAll()通知,喚醒等待隊(duì)列中的所有線程,并使這些線程進(jìn)入鎖池。
    public static void main(String[] args) {
        Runnable r1 = new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                synchronized ("A") {
                    System.out.println("A線程持有了A鎖,等待B鎖");
                    
                    try {
                        "A".wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    synchronized ("B") {
                        System.out.println("A線程持有了A鎖和B鎖");
                    }
                }
            }
        };
        
        Runnable r2 = new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                synchronized ("B") {
                    System.out.println("B線程持有了B鎖,等待A鎖");
                    synchronized ("A") {
                        System.out.println("B線程持有了A鎖和B鎖");
                        //喚醒所有等待A鎖的線程
                        "A".notifyAll();
                    }
                }
            }
        };
        
        Thread threadA = new Thread(r1);
        Thread threadB = new Thread(r2);
        threadA.start();
        threadB.start();
    }
}

wait()等待,是Object中的方法,當(dāng)前線程釋放自己的所標(biāo)記,讓出CPU資源,使當(dāng)前線程進(jìn)入等待隊(duì)列
notify()通知,是Object中的方法,喚醒等待隊(duì)列中的一個(gè)線程,使這個(gè)線程進(jìn)入鎖池。
notifyAll()通知,喚醒等待隊(duì)列中的所有線程,并使這些線程進(jìn)入鎖池。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容