日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
為了讓小白也能看懂這個死鎖Case,我請來了小黑...

小黑有點(diǎn)困,他想休息,又怕耽誤時間,于是準(zhǔn)備小瞇一會。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序設(shè)計(jì)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了寧蒗免費(fèi)建站歡迎大家使用!

為了能按時起來,他設(shè)了鬧鐘,作為程序員,必須得整兩個,防止單點(diǎn)故障。

當(dāng)任意一個鬧鐘響起,小黑就起來把兩個鬧鐘都關(guān)掉,繼續(xù)干活,就像這樣:

public class Clock {
    private BlackBro blackBro;

    public void setBlackBro(BlackBro blackBro) {
        this.blackBro = blackBro;
    }

    public synchronized void ring() {
        System.out.println(Thread.currentThread() + " Clock.ring...");
        blackBro.wake();
    }

    public synchronized void close() {
        System.out.println(Thread.currentThread() + " Clock.close...");
    }
}
public class BlackBro {
    private Clock[] clocks;

    public void setClocks(Clock[] clocks) {
        this.clocks = clocks;
    }

    public synchronized void wake() {
        System.out.println(Thread.currentThread() + "BlackBro.wake...");
        for (Clock clock : clocks) {
            clock.close();
        }
    }
}

為了防止鬧鐘和小黑在執(zhí)行操作期間被人打擾,我貼心地給他們都加上了鎖 —— synchronized。

模擬這個場景將是這樣:

public static void main(String[] args) {
    Clock clock1 = new Clock();
    Clock clock2 = new Clock();
    BlackBro blackBro = new BlackBro();

    clock1.setBlackBro(blackBro);
    clock2.setBlackBro(blackBro);
    blackBro.setClocks(new Clock[]{clock1, clock2});

    // sleep...
    Thread t1 = new Thread(clock1::ring);
    Thread t2 = new Thread(clock2::ring);

    t1.start();
    t2.start();
}

啟動程序發(fā)現(xiàn),陷入了無盡地等待:

Thread[Thread-0,5,main] Clock.ring...
Thread[Thread-1,5,main] Clock.ring...
Thread[Thread-1,5,main]BlackBro.wake...

這是怎么回事?眼尖的同學(xué)肯定發(fā)現(xiàn)問題了。我們看一下 jstack:

Found one Java-level deadlock:
=============================
"Thread-0":
  waiting to lock monitor 0x0000600003ecc000 (object 0x000000070fc52398, a com.demo.BlackBro),
  which is held by "Thread-1"

"Thread-1":
  waiting to lock monitor 0x0000600003ec04e0 (object 0x000000070fc50f88, a com.demo.Clock),
  which is held by "Thread-0"

Java stack information for the threads listed above:
===================================================

原來是死鎖了:我們起了兩個鬧鐘線程,兩個線程各自拿到自己的對象鎖,開始 ring,ring 又都會去喚醒小黑,但小黑對象只有一個,只有一個鬧鐘能順利拿到小黑的對象鎖,小黑被喚醒后又去關(guān)鬧鐘,但卻沒法關(guān)掉,因?yàn)轸[鐘在等小黑喚醒的期間不會被別人打斷,于是鬧鐘在等小黑,小黑在等鬧鐘,形成了死鎖。

我相信稍微仔細(xì)點(diǎn)大家都能發(fā)現(xiàn)這個問題,這是因?yàn)槲野迅蓴_項(xiàng)都排除,只留下非常簡單的框架。如果在一個非常復(fù)雜的系統(tǒng)中,還是很難發(fā)現(xiàn)的。這也是我今天遇到的一個線上問題,花了半天時間才排查出來。

這個 case 教育我們要謹(jǐn)慎使用鎖,尤其是 synchronized;其次如果發(fā)現(xiàn)程序沒有按預(yù)期地執(zhí)行,尤其是該執(zhí)行的沒執(zhí)行,可以留個心眼,看看堆棧是不是有死鎖。

2024 年第一個小case送給你,你學(xué)廢了嗎?


網(wǎng)站欄目:為了讓小白也能看懂這個死鎖Case,我請來了小黑...
分享URL:http://www.5511xx.com/article/cdeiggd.html