自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為了讓小白也能看懂這個(gè)死鎖Case,我請來了小黑...

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

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

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

當(dāng)任意一個(gè)鬧鐘響起,小黑就起來把兩個(gè)鬧鐘都關(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。

模擬這個(gè)場景將是這樣:

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();
}

啟動(dòng)程序發(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:
===================================================

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

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

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

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

責(zé)任編輯:武曉燕 來源: 捉蟲大師
相關(guān)推薦

2017-02-22 15:04:52

2024-11-01 05:10:00

2021-11-01 15:15:37

Context項(xiàng)目代碼

2019-12-27 09:47:05

大數(shù)據(jù)TomcatWeb

2018-12-24 08:46:52

Kubernetes對象模型

2019-11-04 13:09:43

數(shù)據(jù)平臺(tái)架構(gòu)

2022-10-11 08:27:45

Spring事務(wù)管理性能統(tǒng)計(jì)

2020-02-15 17:16:05

Kubernetes容器

2019-11-18 10:38:03

線程池Java框架

2019-10-10 11:10:04

SpringBoot異步編程

2013-09-22 10:34:08

碼農(nóng)機(jī)器學(xué)習(xí)算法

2019-03-26 11:15:34

AI機(jī)器學(xué)習(xí)人工智能

2020-03-31 10:36:07

數(shù)據(jù)平臺(tái)架構(gòu)

2013-03-15 10:35:17

編程語言編程笑話

2018-05-16 10:07:02

監(jiān)控報(bào)警系統(tǒng)

2020-11-16 16:38:30

人工智能AI

2022-12-27 16:31:22

AI繪圖軟件

2018-03-06 10:38:23

云計(jì)算大數(shù)據(jù)人工智能

2017-11-02 12:08:56

2025-02-17 10:09:54

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號