哲學(xué)家進(jìn)餐問題

1965年斜脂,荷蘭計算機(jī)科學(xué)家圖靈獎得主Edsger Wybe Dijkstra提出并解決了一個他稱之為哲學(xué)家進(jìn)餐的同步問題艾恼。這個問題可以簡單地描述如下:五個哲學(xué)家圍坐在一張圓桌周圍,每個哲學(xué)家面前都有一盤通心粉。由于通心粉很滑,所以需要兩把叉子才能夾住。相鄰兩個盤子之間放有一把叉子如下圖所示蜕该。哲學(xué)家的生活中有兩種交替活動時段:即吃飯和思考。當(dāng)一個哲學(xué)家覺得餓了時洲鸠,他就試圖分兩次去取其左邊和右邊的叉子堂淡,每次拿一把,但不分次序扒腕。如果成功地得到了兩把叉子绢淀,就開始吃飯,吃完后放下叉子繼續(xù)思考袜匿。 ??把上面問題中的哲學(xué)家換成線程更啄,把叉子換成競爭的臨界資源,上面的問題就是線程競爭資源的問題居灯。如果沒有經(jīng)過精心的設(shè)計祭务,系統(tǒng)就會出現(xiàn)死鎖、活鎖怪嫌、吞吐量下降等問題

Paste_Image.png
package threadTest;

import java.util.concurrent.Semaphore;

public class test01 {
     public static void main(String[] args) {
            String[] names = { "駱昊", "王大錘", "張三豐", "楊過", "李莫愁" };   // 5位哲學(xué)家的名字
//        ExecutorService es = Executors.newFixedThreadPool(AppContext.NUM_OF_PHILO); // 創(chuàng)建固定大小的線程池
//        for(int i = 0, len = names.length; i < len; ++i) {
//            es.execute(new Philosopher(i, names[i]));   // 啟動線程
//        }
//        es.shutdown();
            for(int i = 0, len = names.length; i < len; ++i) {
                new Thread(new Philosopher(i, names[i])).start();
            }
        }
}

class AppContext{
    public static final int NUM_OF_FORKS=5; //叉子數(shù)量(資源)
    public static final int NUM_OF_PHILO=5; //哲學(xué)家數(shù)量(線程)
    
    public static Semaphore[] forks;    //叉子的信號量
    public static Semaphore counter;    //哲學(xué)家的信號量

    static{
        forks=new Semaphore[NUM_OF_FORKS];
        
        for(int i=0,len=forks.length;i<len;i++){
            forks[i]=new Semaphore(1);  //每個叉子的信號量為1
        }
        
        counter=new Semaphore(NUM_OF_PHILO-1);  //如果有n個哲學(xué)家义锥,最多只允許n-1人同時取叉子
    }
    
    /**
     * 取得叉子
     * @param index 第幾個哲學(xué)家
     * @param leftFirst 是否先取得左邊的叉子
     * @throws InterruptedException
     */
    public static void putOnFork(int index,boolean leftFirst)throws InterruptedException{
        if(leftFirst){
            forks[index].acquire();
            forks[(index+1)%NUM_OF_PHILO].acquire();
        }else{
            forks[(index+1)%NUM_OF_PHILO].acquire();
            forks[index].acquire();
        }
        
    }
    
    /**
     * 放回叉子
     * @param index 第幾個哲學(xué)家
     * @param leftFirst 是否先放回左邊的叉子
     * @throws InterruptedException
     */
    public static void putDownFork(int index,boolean leftFirst)throws InterruptedException{
        if(leftFirst){
            forks[index].release();
            forks[(index+1)%NUM_OF_PHILO].release();
        }else{
            forks[(index+1)%NUM_OF_PHILO].release();
            forks[index].release();
        }
        
    }
    
}

/**
 * 哲學(xué)家
 *
 */
class Philosopher implements Runnable {
    private int index;      // 編號
    private String name;    // 名字

    public Philosopher(int index, String name) {
        this.index = index;
        this.name = name;
    }
    @Override
    public void run() {
        while(true) {
            try {
                AppContext.counter.acquire();
                boolean leftFirst = index % 2 == 0;
                AppContext.putOnFork(index, leftFirst);
                System.out.println(name + "正在吃意大利面(通心粉)...");   // 取到兩個叉子就可以進(jìn)食
                AppContext.putDownFork(index, leftFirst);
                AppContext.counter.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}











最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市岩灭,隨后出現(xiàn)的幾起案子拌倍,更是在濱河造成了極大的恐慌,老刑警劉巖噪径,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柱恤,死亡現(xiàn)場離奇詭異,居然都是意外死亡找爱,警方通過查閱死者的電腦和手機(jī)梗顺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來车摄,“玉大人寺谤,你說我怎么就攤上這事∷辈ィ” “怎么了变屁?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長意狠。 經(jīng)常有香客問我粟关,道長,這世上最難降的妖魔是什么环戈? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任闷板,我火速辦了婚禮获列,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蛔垢。我一直安慰自己,他們只是感情好迫悠,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布鹏漆。 她就那樣靜靜地躺著,像睡著了一般创泄。 火紅的嫁衣襯著肌膚如雪艺玲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天鞠抑,我揣著相機(jī)與錄音饭聚,去河邊找鬼。 笑死搁拙,一個胖子當(dāng)著我的面吹牛秒梳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播箕速,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼酪碘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了盐茎?” 一聲冷哼從身側(cè)響起兴垦,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎字柠,沒想到半個月后探越,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡窑业,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年钦幔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片数冬。...
    茶點(diǎn)故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡节槐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拐纱,到底是詐尸還是另有隱情铜异,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布秸架,位于F島的核電站揍庄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏东抹。R本人自食惡果不足惜蚂子,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一沃测、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧食茎,春花似錦蒂破、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至哎媚,卻和暖如春喇伯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拨与。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工稻据, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人买喧。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓捻悯,卻偏偏與公主長得像,于是被迫代替她去往敵國和親岗喉。 傳聞我的和親對象是個殘疾皇子秋度,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容