欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

哲學(xué)家進(jìn)餐java代碼 哲學(xué)家進(jìn)餐問(wèn)題3種代碼

JAVA中的哲學(xué)家問(wèn)題怎么弄,誰(shuí)給我代碼

設(shè)計(jì)題目:哲學(xué)家進(jìn)餐問(wèn)題

目前累計(jì)服務(wù)客戶近千家,積累了豐富的產(chǎn)品開(kāi)發(fā)及服務(wù)經(jīng)驗(yàn)。以網(wǎng)站設(shè)計(jì)水平和技術(shù)實(shí)力,樹(shù)立企業(yè)形象,為客戶提供成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、網(wǎng)站策劃、網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)絡(luò)營(yíng)銷、VI設(shè)計(jì)、網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。創(chuàng)新互聯(lián)始終以務(wù)實(shí)、誠(chéng)信為根本,不斷創(chuàng)新和提高建站品質(zhì),通過(guò)對(duì)領(lǐng)先技術(shù)的掌握、對(duì)創(chuàng)意設(shè)計(jì)的研究、對(duì)客戶形象的視覺(jué)傳遞、對(duì)應(yīng)用系統(tǒng)的結(jié)合,為客戶提供更好的一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶,共同發(fā)展進(jìn)步。

一、 設(shè)計(jì)題目:哲學(xué)家進(jìn)餐問(wèn)題

二、 設(shè)計(jì)要求

1、 分析題目

哲學(xué)家有N個(gè),也定全體到齊后開(kāi)始討論,在討論的間隙哲學(xué)家進(jìn)餐,(1)每個(gè)人只能拿起位于自己兩邊放著的刀、叉,合成一對(duì)才可以用餐;(2)用餐后每人必須將刀、叉放回原處。可以想象,如果每個(gè)哲學(xué)家都彬彬有禮,并且高談闊論,輪流吃飯,則這種融洽的氣氛可以長(zhǎng)久地保持下去。但可能出現(xiàn)這樣一種情景:當(dāng)每個(gè)人都拿起自己左手的刀(叉),并且同時(shí)去拿自己右手邊的叉(刀)時(shí),會(huì)發(fā)生什么情況:每個(gè)人拿著一支餐具,盯著自己右手邊的那位哲學(xué)家手里的一支餐具,處于僵持狀態(tài)。這就是發(fā)生了“線程死鎖”。需要指出的是,線程死鎖并不是必然會(huì)發(fā)生,在某些情況下,可能會(huì)非常偶然。

2、 解決方案

一般來(lái)說(shuō),要出現(xiàn)死鎖必須同時(shí)據(jù)別以下4個(gè)條件。因此,只要能夠盡可能地破壞這4個(gè)條件中的任意一個(gè),就可以避免死鎖的出現(xiàn)。(1)互斥條件,即至少存在一個(gè)資源,不能被多個(gè)線程同時(shí)共享。(2)至少存在一個(gè)線程,它擁有一個(gè)資源,并等待獲得另一個(gè)線程當(dāng)前所擁有的資源。(3)線程擁有的資源不能被強(qiáng)行剝奪,只能有線程資源釋放。(4)線程對(duì)資源的請(qǐng)求形成一個(gè)環(huán)。

三、 源代碼

//DishWare.java

//定義一個(gè)DishWareBean進(jìn)行屬性和方法封裝

public class DishWare

{

private String name;

public DishWare(String name)

{

this.name=name;

}

public String getNumber()

{

return name;

}

}

//Philospher.java

import java.util.*; //包含常用的數(shù)據(jù)類型類

public class Philospher extends Thread

{

private DishWare Knife;

private DishWare Fork;

private String name;

private static Random random=new Random();

public Philospher(String name,DishWare Knife,DishWare Fork) //構(gòu)造函數(shù),變量初始化

{

this.name=name;

this.Knife=Knife;

this.Fork=Fork;

}

public String getNumber()

{

return name;

}

public void run() //多線程的實(shí)現(xiàn)方法run()

{

try{

sleep(random.nextInt(3));

}

catch(InterruptedException e){}

synchronized(Knife){ //線程的同步,使用synchronized關(guān)鍵詞

System.out.println(this.getNumber()+" has "+Knife.getNumber()+" and wait for "+Fork.getNumber());

synchronized(Fork){

System.out.println(this.getNumber()+" eating");

}

}

}

public static void main(String args[])

{

//建立刀叉對(duì)象

DishWare knife1=new DishWare("Knife1");

DishWare fork1=new DishWare("Fork1");

DishWare knife2=new DishWare("Knife2");

DishWare fork2=new DishWare("Fork2");

//建立哲學(xué)家對(duì)象,并在其兩邊擺放刀叉

Philospher philospher1=new Philospher("philospher1",knife1,fork1);

Philospher philospher2=new Philospher("philospher2",fork1,knife2);

Philospher philospher3=new Philospher("philospher3",knife2,fork2);

Philospher philospher4=new Philospher("philospher4",fork2,knife1);

//啟動(dòng)3個(gè)線程,用start方法開(kāi)始線程

philospher1.start();

philospher2.start();

philospher3.start();

philospher4.start();

}

}

求“哲學(xué)家進(jìn)餐問(wèn)題”的偽碼

# define N 5 /* 哲學(xué)家數(shù)目 */

# define LEFT (i-1+N)%N /* i的左鄰號(hào)碼 */

# define RIGHT (i+1)%N /* i的右鄰號(hào)碼 */

# define THINKING 0 /* 哲學(xué)家正在思考 */

# define HUNGRY 1 /* 哲學(xué)家想取得叉子 */

# define EATING 2 /* 哲學(xué)家正在吃面 */

typedef int semaphore; /* 信號(hào)量是一個(gè)特殊的整型變量 */

int state[N]; /* 記錄每個(gè)人狀態(tài)的數(shù)組 */

semaphore mutex=1; /* 臨界區(qū)互斥 */

semaphore s[N]; /* 每個(gè)哲學(xué)家一個(gè)信號(hào)量 */

void philosopher(int i) /* i:哲學(xué)家號(hào)碼,從0到N-1 */

{

while(TRUE)

{ /* 無(wú)限循環(huán) */

think(); /* 哲學(xué)家正在思考 */

take_forks(i);

/* 需要兩只叉子,或者阻塞 */

eat(); /* 進(jìn)餐 */

put_forks(i);

/* 把兩把叉子同時(shí)放回桌子 */

}

}

void take_forks(int i) /* i:哲學(xué)家號(hào)碼從0到N-1 */

{

down(mutex); /* 進(jìn)入臨界區(qū) */

state[i]=HUNGRY; /* 記錄下哲學(xué)家i饑餓的事實(shí) */

test(i); /* 試圖得到兩只叉子 */

up(mutex); /* 離開(kāi)臨界區(qū) */

down(s[i]); /* 如果得不到叉子就阻塞 */

}

void put_forks(int I) /* i:哲學(xué)家號(hào)碼從0到N-1 */

{

down(mutex); /* 進(jìn)入臨界區(qū) */

state[i]=THINKING; /* 哲學(xué)家進(jìn)餐結(jié)束 */

test(LEFT); /* 看一下左鄰居現(xiàn)在是否能進(jìn)餐 */

test(RIGHT); /* 看一下右鄰居現(xiàn)在是否能進(jìn)餐 */

up(mutex); /* 離開(kāi)臨界區(qū) */

}

void test(i) /* i:哲學(xué)家號(hào)碼從0到N-1 */

{

if(state[i]==HUNGRYstate[LEFT]!=EATING

state[RIGHT]!=EATING)

{

state[i]=EATING;

up(s[i]);

}

}

哲學(xué)家進(jìn)餐問(wèn)題的算法與實(shí)現(xiàn)

1.哲學(xué)家進(jìn)餐問(wèn)題:

(1) 在什么情況下5 個(gè)哲學(xué)家全部吃不上飯考慮兩種實(shí)現(xiàn)的方式,如下:

A. 算法描述: void philosopher(int i) /*i:哲學(xué)家編號(hào),從0 到4*/ {while (TRUE) { think( ); /*哲學(xué)家正在思考*/ take_fork(i); /*取左側(cè)的筷子*/ take_fork((i+1) % N); /*取左側(cè)筷子;%為取模運(yùn)算*/eat( ); /*吃飯*/put_fork(i); /*把左側(cè)筷子放回桌子*/ put_fork((i+1) % N); /*把右側(cè)筷子放回桌子*/ } } 分析:假如所有的哲學(xué)家都同時(shí)拿起左側(cè)筷子,看到右側(cè)筷子不可用,又都放下左側(cè)筷子,等一會(huì)兒,又同時(shí)拿起左側(cè)筷子,如此這般,永遠(yuǎn)重復(fù)。對(duì)于這種情況,即所有的程序都在無(wú)限期地運(yùn)行,但是都無(wú)法取得任何進(jìn)展,即出現(xiàn)饑餓,所有哲學(xué)家都吃不上飯。

B.算法描述:規(guī)定在拿到左側(cè)的筷子后,先檢查右面的筷子是否可用。如果不可用,則先放下左側(cè)筷子,等一段時(shí)間再重復(fù)整個(gè)過(guò)程。分析:當(dāng)出現(xiàn)以下情形,在某一個(gè)瞬間,所有的哲學(xué)家都同時(shí)啟動(dòng)這個(gè)算法,拿起左側(cè)的筷子,而看到右側(cè)筷子不可用,又都放下左側(cè)筷子,等一會(huì)兒,又同時(shí)拿起左側(cè)筷子……如此這樣永遠(yuǎn)重復(fù)下去。對(duì)于這種情況,所有的程序都在運(yùn)行,但卻無(wú)法取得進(jìn)展,即出現(xiàn)饑餓,所有的哲學(xué)家都吃不上飯。

(2) 描述一種沒(méi)有人餓死(永遠(yuǎn)拿不到筷子)算法。考慮了四種實(shí)現(xiàn)的方式(A、B、C、D):

A.原理:至多只允許四個(gè)哲學(xué)家同時(shí)進(jìn)餐,以保證至少有一個(gè)哲學(xué)家能夠進(jìn)餐,最終總會(huì)釋放出他所使用過(guò)的兩支筷子,從而可使更多的哲學(xué)家進(jìn)餐。以下將room 作為信號(hào)量,只允許4 個(gè)哲學(xué)家同時(shí)進(jìn)入餐廳就餐,這樣就能保證至少有一個(gè)哲學(xué)家可以就餐,而申請(qǐng)進(jìn)入餐廳的哲學(xué)家進(jìn)入room 的等待隊(duì)列,根據(jù)FIFO 的原則,總會(huì)進(jìn)入到餐廳就餐,因此不會(huì)出現(xiàn)餓死和死鎖的現(xiàn)象。

偽碼: semaphore chopstick[5]={1,1,1,1,1}; semaphore room=4; void philosopher(int i) { while(true) {think(); wait(room); //請(qǐng)求進(jìn)入房間進(jìn)餐 wait(chopstick[i]); //請(qǐng)求左手邊的筷子 wait(chopstick[(i+1)%5]); //請(qǐng)求右手邊的筷子 eat(); signal(chopstick[(i+1)%5]); //釋放右手邊的筷子 signal(chopstick[i]); //釋放左手邊的筷子 signal(room); //退出房間釋放信號(hào)量room } }

B.原理:僅當(dāng)哲學(xué)家的左右兩支筷子都可用時(shí),才允許他拿起筷子進(jìn)餐。

方法1:利用AND 型信號(hào)量機(jī)制實(shí)現(xiàn):根據(jù)課程講述,在一個(gè)原語(yǔ)中,將一段代碼同時(shí)需要的多個(gè)臨界資源,要么全部分配給它,要么一個(gè)都不分配,因此不會(huì)出現(xiàn)死鎖的情形。當(dāng)某些資源不夠時(shí)阻塞調(diào)用進(jìn)程;由于等待隊(duì)列的存在,使得對(duì)資源的請(qǐng)求滿足FIFO 的要求,因此不會(huì)出現(xiàn)饑餓的情形。

偽碼: semaphore chopstick[5]={1,1,1,1,1}; void philosopher(int I) { while(true) { think();Swait(chopstick[(I+1)]%5,chopstick[I]); eat(); Ssignal(chopstick[(I+1)]%5,chopstick[I]);} } 方法2:利用信號(hào)量的保護(hù)機(jī)制實(shí)現(xiàn)。通過(guò)信號(hào)量mutex對(duì)eat()之前的取左側(cè)和右側(cè)筷子的操作進(jìn)行保護(hù),使之成為一個(gè)原子操作,這樣可以防止死鎖的出現(xiàn)。偽碼: semaphore mutex = 1 ; semaphorechopstick[5]={1,1,1,1,1};void philosopher(int I) { while(true) { think(); wait(mutex);wait(chopstick[(I+1)]%5); wait(chopstick[I]); signal(mutex); eat();signal(chopstick[(I+1)]%5); signal(chopstick[I]); } }

C.原理:規(guī)定奇數(shù)號(hào)的哲學(xué)家先拿起他左邊的筷子,然后再去拿他右邊的筷子;而偶數(shù)號(hào)的哲學(xué)家則相反.按此規(guī)定,將是1,2號(hào)哲學(xué)家競(jìng)爭(zhēng)1號(hào)筷子,3,4號(hào)哲學(xué)家競(jìng)爭(zhēng)3號(hào)筷子.即五個(gè)哲學(xué)家都競(jìng)爭(zhēng)奇數(shù)號(hào)筷子,獲得后,再去競(jìng)爭(zhēng)偶數(shù)號(hào)筷子,最后總會(huì)有一個(gè)哲學(xué)家能獲得兩支筷子而進(jìn)餐。而申請(qǐng)不到的哲學(xué)家進(jìn)入阻塞等待隊(duì)列,根FIFO原則,則先申請(qǐng)的哲學(xué)家會(huì)較先可以吃飯,因此不會(huì)出現(xiàn)餓死的哲學(xué)家。

偽碼: semaphore chopstick[5]={1,1,1,1,1}; void philosopher(int i) { while(true) { think(); if(i%2== 0) //偶數(shù)哲學(xué)家,先右后左。 { wait (chopstick[ i + 1 ] mod 5) ; wait (chopstick[ i]) ;eat(); signal (chopstick[ i + 1 ] mod 5) ; signal (chopstick[ i]) ; } Else //奇數(shù)哲學(xué)家,先左后右。 { wait (chopstick[ i]) ; wait (chopstick[ i +1 ] mod 5) ; eat(); signal (chopstick[ i]) ; signal (chopstick[ i + 1 ] mod 5); } }

D.利用管程機(jī)制實(shí)現(xiàn)(最終該實(shí)現(xiàn)是失敗的,見(jiàn)以下分析):原理:不是對(duì)每只筷子設(shè)置信號(hào)量,而是對(duì)每個(gè)哲學(xué)家設(shè)置信號(hào)量。test()函數(shù)有以下作用:

a. 如果當(dāng)前處理的哲學(xué)家處于饑餓狀態(tài)且兩側(cè)哲學(xué)家不在吃飯狀態(tài),則當(dāng)前哲學(xué)家通過(guò) test()函數(shù)試圖進(jìn)入吃飯狀態(tài)。

b. 如果通過(guò)test()進(jìn)入吃飯狀態(tài)不成功,那么當(dāng)前哲學(xué)家就在該信號(hào)量阻塞等待,直到其他的哲學(xué)家進(jìn)程通過(guò)test()將該哲學(xué)家的狀態(tài)設(shè)置為EATING。

c. 當(dāng)一個(gè)哲學(xué)家進(jìn)程調(diào)用put_forks()放下筷子的時(shí)候,會(huì)通過(guò)test()測(cè)試它的鄰居,如果鄰居處于饑餓狀態(tài),且該鄰居的鄰居不在吃飯狀態(tài),則該鄰居進(jìn)入吃飯狀態(tài)。由上所述,該算法不會(huì)出現(xiàn)死鎖,因?yàn)橐粋€(gè)哲學(xué)家只有在兩個(gè)鄰座都不在進(jìn)餐時(shí),才允許轉(zhuǎn)換到進(jìn)餐狀態(tài)。該算法會(huì)出現(xiàn)某個(gè)哲學(xué)家適終無(wú)法吃飯的情況,即當(dāng)該哲學(xué)家的左右兩個(gè)哲學(xué)家交替處在吃飯的狀態(tài)的時(shí)候,則該哲學(xué)家始終無(wú)法進(jìn)入吃飯的狀態(tài),因此不滿足題目的要求。但是該算法能夠?qū)崿F(xiàn)對(duì)于任意多位哲學(xué)家的情況都能獲得最大的并行度,因此具有重要的意義。

偽碼:#define N 5 /* 哲學(xué)家人數(shù)*/#define LEFT (i-1+N)%N /* i的左鄰號(hào)碼 */ #define RIGHT (i+1)%N /* i的右鄰號(hào)碼 */ typedef enum { THINKING, HUNGRY, EATING } phil_state; /*哲學(xué)家狀態(tài)*/ monitor dp /*管程*/ { phil_state state[N]; semaphore mutex =1; semaphore s[N];/*每個(gè)哲學(xué)家一個(gè)信號(hào)量,初始值為0*/void test(int i) { if ( state[i] == HUNGRY state[LEFT(i)] != EATING state[RIGHT(i)] != EATING ) { state[i] = EATING; V(s[i]); } } void get_forks(inti) { P(mutex); state[i] = HUNGRY; test(i); /*試圖得到兩支筷子*/ V(mutex); P(s[i]); /*得不到筷子則阻塞*/ } void put_forks(int i) { P(mutex); state[i]= THINKING;test(LEFT(i)); /*看左鄰是否進(jìn)餐*/ test(RIGHT(i)); /*看右鄰是否進(jìn)餐*/ V(mutex); } } 哲學(xué)家進(jìn)程如下: void philosopher(int process) { while(true) { think();get_forks(process); eat(); put_forks(process); } }

2.理發(fā)師問(wèn)題:一個(gè)理發(fā)店有一個(gè)入口和一個(gè)出口。理發(fā)店內(nèi)有一個(gè)可站5 位顧客的站席區(qū)、4 個(gè)單人沙發(fā)、3 個(gè)理發(fā)師及其專用理發(fā)工具、一個(gè)收銀臺(tái)。新來(lái)的顧客坐在沙發(fā)上等待;沒(méi)有空沙發(fā)時(shí),可在站席區(qū)等待;站席區(qū)滿時(shí),只能在入口外等待。理發(fā)師可從事理發(fā)、收銀和休息三種活動(dòng)。

理發(fā)店的活動(dòng)滿足下列條件:

1)休息的理發(fā)師是坐地自己專用的理發(fā)椅上,不會(huì)占用顧客的沙發(fā);

2)處理休息狀態(tài)的理發(fā)師可為在沙發(fā)上等待時(shí)間最長(zhǎng)的顧客理發(fā);

3)理發(fā)時(shí)間長(zhǎng)短由理發(fā)師決定;

4)在站席區(qū)等待時(shí)間最長(zhǎng)的顧客可坐到空閑的理發(fā)上;

5)任何時(shí)刻最多只能有一個(gè)理發(fā)師在收銀。試用信號(hào)量機(jī)制或管程機(jī)制實(shí)現(xiàn)理發(fā)師進(jìn)程和顧客進(jìn)程。

原理:

(1) customer 進(jìn)程:首先檢查站席區(qū)是否已滿(stand_capacity),若滿選擇離開(kāi),否則進(jìn)入站席區(qū),即進(jìn)入理發(fā)店。在站席區(qū)等待沙發(fā)的空位(信號(hào)量sofa),如果沙發(fā)已滿,則進(jìn)入阻塞等待隊(duì)列,直到出現(xiàn)空位,在站席區(qū)中等待時(shí)間最長(zhǎng)的顧客離開(kāi)站席區(qū)(stand_capacity)。坐到沙發(fā)上,等待理發(fā)椅(barber_chair),如果理發(fā)椅已滿,則進(jìn)入阻塞等待隊(duì)列,直到出現(xiàn)空位,在沙發(fā)上等待時(shí)間最長(zhǎng)的顧客離開(kāi)沙發(fā)(釋放信號(hào)量sofa)。坐到理發(fā)椅上,釋放準(zhǔn)備好的信號(hào)(customer_ready),獲得該理發(fā)師的編號(hào)(0~1 的數(shù)字)。等待理發(fā)師理發(fā)結(jié)束(finished[barber_number])。在離開(kāi)理發(fā)椅之前付款(payment),等待收據(jù) (receipt),離開(kāi)理發(fā)椅(leave_barberchair)。最后離開(kāi)理發(fā)店。

這里需要注意幾點(diǎn):

a) 首先是幾個(gè)需要進(jìn)行互斥處理的地方,主要包括:進(jìn)入站席區(qū)、進(jìn)入沙發(fā)、進(jìn)入理發(fā)椅和付款幾個(gè)地方。

b) 通過(guò)barber_chair保證一個(gè)理發(fā)椅上最多只有一名顧客。但這也不夠,因?yàn)閱螒{ baber_chair 無(wú)法保證一名顧客離開(kāi)理發(fā)椅之前,另一位顧客不會(huì)坐到該理發(fā)椅上,因此增加信號(hào)量leave_barberchair,讓顧客離開(kāi)理發(fā)椅后,釋放該信號(hào),而理發(fā)師接收到該信號(hào)后才釋放barber_chair 等待下一位顧客。

c) 在理發(fā)的過(guò)程中,需要保證是自己理發(fā)完畢,才能夠進(jìn)行下面的付款、離開(kāi)理發(fā)椅的活動(dòng)。這個(gè)機(jī)制是通過(guò)customer 進(jìn)程獲得給他理發(fā)的理發(fā)師編號(hào)來(lái)實(shí)現(xiàn)的,這樣,當(dāng)該編號(hào)的理發(fā)師釋放對(duì)應(yīng)的finished[i]信號(hào)的時(shí)候,該顧客才理發(fā)完畢。

d) 理發(fā)師是通過(guò)mutex 信號(hào)量保證他們每個(gè)人同時(shí)只進(jìn)行一項(xiàng)操作(理發(fā)或者收款)。

e) 為了保證該顧客理發(fā)完畢后馬上可以付款離開(kāi),就應(yīng)該保證給該顧客理發(fā)的理發(fā)師在理發(fā)完畢后馬上到收銀臺(tái)進(jìn)入收款操作而不是給下一位顧客服務(wù)。在偽碼中由以下機(jī)制實(shí)現(xiàn):即顧客在釋放離開(kāi)理發(fā)椅的信號(hào)前,發(fā)出付款的信號(hào)。這樣該理發(fā)師得不到顧客的離開(kāi)理發(fā)椅的信號(hào),不能進(jìn)入下一個(gè)循環(huán)為下一名顧客服務(wù),而只能進(jìn)入收款臺(tái)的收款操作。直到顧客接到收據(jù)后,才釋放離開(kāi)理發(fā)椅的信號(hào),離開(kāi)理發(fā)椅,讓理發(fā)師釋放該理發(fā)椅的信號(hào),讓下一位等待的顧客坐到理發(fā)椅上。

(2)barber 進(jìn)程首先將該理發(fā)師的編號(hào)壓入隊(duì)列,供顧客提取。等待顧客坐到理發(fā)椅坐好(信號(hào)量 customer_ready),開(kāi)始理發(fā),理發(fā)結(jié)束后釋放結(jié)束信號(hào)(finished[i])。等待顧客離開(kāi)理發(fā)椅(leave_barberchair)(期間去收銀臺(tái)進(jìn)行收款活動(dòng)),釋放理發(fā)椅空閑信號(hào)(barber_chair),等待下一位顧客坐上來(lái)。

(3)cash(收銀臺(tái))進(jìn)程等待顧客付款(payment),執(zhí)行收款操作,收款操作結(jié)束,給付收據(jù)(receipt)。信號(hào)量總表:信號(hào)量 waitsignal stand_capacity 顧客等待進(jìn)入理發(fā)店顧客離開(kāi)站席區(qū) sofa 顧客等待坐到沙發(fā)顧客離開(kāi)沙發(fā) barber_chair 顧客等待空理發(fā)椅理發(fā)師釋放空理發(fā)椅 customer_ready 理發(fā)師等待,直到一個(gè)顧客坐到理發(fā)椅顧客坐到理發(fā)椅上,給理發(fā)師發(fā)出信號(hào) mutex 等待理發(fā)師空閑,執(zhí)行理發(fā)或收款操作理發(fā)師執(zhí)行理發(fā)或收款結(jié)束,進(jìn)入空閑狀態(tài) mutex1執(zhí)行入隊(duì)或出隊(duì)等待入隊(duì)或出隊(duì)結(jié)束,釋放信號(hào) finished[i] 顧客等待對(duì)應(yīng)編號(hào)理發(fā)師理發(fā)結(jié)束理發(fā)師理發(fā)結(jié)束,釋放信號(hào) leave_barberchair 理發(fā)師等待顧客離開(kāi)理發(fā)椅顧客付款完畢得到收據(jù),離開(kāi)理發(fā)椅釋放信號(hào) payment 收銀員等待顧客付款顧客付款,發(fā)出信號(hào) receipt 顧客等待收銀員收、開(kāi)具收據(jù)收銀員收款結(jié)束、開(kāi)具收據(jù),釋放信號(hào)

偽碼: semaphore stand_capacity=5; semaphore sofa=4; semaphorebarber_chair=3; semaphore customer_ready=0; semaphore mutex=3; semaphoremutex1=1; semaphore finished[3]={0,0,0}; semaphore leave_barberchair=0;semaphore payment=0; semaphore receipt=0; void customer() { int barber_number;wait(stand_capacity); //等待進(jìn)入理發(fā)店 enter_room(); //進(jìn)入理發(fā)店 wait(sofa); //等待沙發(fā) leave_stand_section(); //離開(kāi)站席區(qū) signal(stand_capacity); sit_on_sofa(); //坐在沙發(fā)上 wait(barber_chair); //等待理發(fā)椅 get_up_sofa(); //離開(kāi)沙發(fā) signal(sofa); wait(mutex1);sit_on_barberchair(); //坐到理發(fā)椅上 signal(customer_ready); barber_number=dequeue(); //得到理發(fā)師編號(hào) signal(mutex1); wait(finished[barber_number]);//等待理發(fā)結(jié)束 pay(); //付款 signal(payment); //付款 wait(receipt); //等待收據(jù) get_up_barberchair(); //離開(kāi)理發(fā)椅 signal(leave_barberchair); //發(fā)出離開(kāi)理發(fā)椅信號(hào) exit_shop(); //了離開(kāi)理發(fā)店 } void barber(int i) { while(true) { wait(mutex1);enqueue(i); //將該理發(fā)師的編號(hào)加入隊(duì)列 signal(mutex1); wait(customer_ready); //等待顧客準(zhǔn)備好 wait(mutex); cut_hair(); //理發(fā) signal(mutex); signal(finished[i]); //理發(fā)結(jié)束 wait(leave_barberchair); //等待顧客離開(kāi)理發(fā)椅信號(hào) signal(barber_chair); //釋放barber_chair 信號(hào) } } void cash() //收銀 { while(true) { wait(payment); //等待顧客付款 wait(mutex); //原子操作 get_pay(); //接受付款 give_receipt(); //給顧客收據(jù) signal(mutex); signal(receipt); //收銀完畢,釋放信號(hào) } }

分析:在分析該問(wèn)題過(guò)程中,出現(xiàn)若干問(wèn)題,是參閱相關(guān)資料后才認(rèn)識(shí)到這些問(wèn)題的隱蔽性和嚴(yán)重性的,主要包括:

(1)在顧客進(jìn)程,如果是在釋放leave_barberchair 信號(hào)之后進(jìn)行付款動(dòng)作的話,很容易造成沒(méi)有收銀員為其收款的情形,原因是:為該顧客理發(fā)的理發(fā)師收到 leave_barberchair 信號(hào)后,釋放barber_chair 信號(hào),另外一名顧客坐到理發(fā)椅上,該理發(fā)師有可能為這另外一名顧客理發(fā),而沒(méi)有為剛理完發(fā)的顧客收款。為解決這個(gè)問(wèn)題,就是采取在釋放leave_barberchair 信號(hào)之前,完成付款操作。這樣該理發(fā)師無(wú)法進(jìn)入下一輪循環(huán)為另外顧客服務(wù),只能到收銀臺(tái)收款。

(2)本算法是通過(guò)給理發(fā)師編號(hào)的方式,當(dāng)顧客坐到某理發(fā)椅上也同時(shí)獲得理發(fā)師的編號(hào),如此,當(dāng)該理發(fā)師理發(fā)結(jié)束,釋放信號(hào),顧客只有接收到為其理發(fā)的理發(fā)師的理發(fā)結(jié)束信號(hào)才會(huì)進(jìn)行付款等操作。這樣實(shí)現(xiàn),是為避免這樣的錯(cuò)誤,即:如果僅用一個(gè)finished 信號(hào)量的話,很容易出現(xiàn)別的理發(fā)師理發(fā)完畢釋放了finished 信號(hào),把正在理發(fā)的這位顧客趕去付款,而已經(jīng)理完發(fā)的顧客卻被阻塞在理發(fā)椅上的情形。當(dāng)然也可以為顧客進(jìn)行編號(hào),讓理發(fā)師獲取他理發(fā)的顧客的編號(hào),但這樣就會(huì)限制顧客的數(shù)量,因?yàn)閒inished[] 數(shù)組不能是無(wú)限的。而為理發(fā)師編號(hào),則只需要三個(gè)元素即可。

哲學(xué)家進(jìn)餐問(wèn)題,java實(shí)現(xiàn)

public class Scientist extends Thread {

/*

* @author Bore

* @mail z

* @time / /

* 哲學(xué)家進(jìn)餐 個(gè)哲學(xué)家 只筷子

* 哲學(xué)家通過(guò)getChopsticks()方法 來(lái)取筷子

* 當(dāng)哲學(xué)家同時(shí)獲得左邊和右邊兩只筷子后才可以進(jìn)餐 否則把已經(jīng)得到的筷子也釋放

* 如果一直筷子也沒(méi)有 進(jìn)程阻塞 等待其他哲學(xué)家釋放資源

* 進(jìn)程后 釋放已經(jīng)獲得的資源

*/

static byte[] chopsticks={ };//五只筷子

public Scientist(String name){

super(name);

}

public void run() {

getChopsticks();

}

public void getChopsticks(){//開(kāi)始搶筷子

int tem=Integer parseInt(this getName() substring( ));//獲取哲學(xué)家編號(hào)

if(tem== ){//如果是第一位科學(xué)家 先搶左邊的筷子

if(leftChopsticks(tem)){//如何獲取了左邊的筷子

if(rightChopsticks(tem)){//如果獲取了右邊的筷子

eating();//開(kāi)始吃飯

freeLeftChopsticks(tem);//釋放左邊筷子

freeRightChopsticks(tem);//釋放右邊筷子

}else{

freeLeftChopsticks(tem);

System out println( 由于 +this getName()+ 無(wú)法獲得右手邊的筷子 所以他把已獲得的左手的筷子也釋放了! );

try {

this sleep( );

} catch (InterruptedException e) {

e printStackTrace();

}

getChopsticks();

}

}else{

System out println(this getName()+ 暫時(shí)無(wú)法獲取兩只筷子 準(zhǔn)備休眠! );

try {

this sleep( );

} catch (InterruptedException e) {

e printStackTrace();

}

getChopsticks();

}

}else{//其他情況先搶右邊的筷子

if(rightChopsticks(tem)){//先搶右手邊的筷子

if(leftChopsticks(tem)){//如果獲得了右手邊的 去搶左手邊的筷子

eating();//如果獲得了兩只筷子 開(kāi)始吃飯

freeLeftChopsticks(tem);//吃完了 釋放左手邊的筷子

freeRightChopsticks(tem);//釋放右手邊的筷子

}else{

freeRightChopsticks(tem);

System out println( 由于 +this getName()+ 無(wú)法獲得左手邊的筷子 所以他把已獲得的右手的筷子也釋放了! );

try {

this sleep( );

} catch (InterruptedException e) {

e printStackTrace();

}

getChopsticks();

}

}else{

System out println(this getName()+ 暫時(shí)無(wú)法獲取兩只筷子 準(zhǔn)備休眠! );

try {

this sleep( );

} catch (InterruptedException e) {

e printStackTrace();

}

getChopsticks();

}

}

}

public boolean leftChopsticks(int tem){//獲取左手邊筷子

if(chopsticks[tem]== ){

chopsticks[tem]= ;

System out println(this getName()+ 左手邊筷子已獲得! );

return true;

}else{

System out println(this getName()+ 左手邊筷子已被哲學(xué)家 +(tem )+ 搶走! );

return false;

}

}

public boolean rightChopsticks(int tem){//獲取右手邊筷子

int i=(tem+ )% ;

if(chopsticks[i]== ){

chopsticks[i]= ;

System out println(this getName()+ 右手邊筷子已獲得! );

return true;

}else{

System out println(this getName()+ 右手邊筷子已被哲學(xué)家 +i+ 搶走! );

return false;

}

}

public void freeLeftChopsticks(int tem){//獲取左手邊筷子

chopsticks[tem]= ;

System out println(this getName()+ 左手邊筷子已釋放! );

}

public void freeRightChopsticks(int tem){//獲取右手邊筷子

int i=(tem+ )% ;

chopsticks[i]= ;

System out println(this getName()+ 右手邊筷子已釋放! );

}

public void eating(){//開(kāi)始進(jìn)餐

System out println( * +this getName()+ 兩只手都有了筷子 所以開(kāi)始吃飯! );

}

/**

* 主函數(shù)

*/

public static void main(String[] args) {

for(int i= ; i ; i++){

new Scientist( 哲學(xué)家 +i) start();

}

}

lishixinzhi/Article/program/Java/hx/201311/25798

網(wǎng)頁(yè)題目:哲學(xué)家進(jìn)餐java代碼 哲學(xué)家進(jìn)餐問(wèn)題3種代碼
文章鏈接:http://chinadenli.net/article36/dodpppg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT品牌網(wǎng)站建設(shè)網(wǎng)站策劃微信公眾號(hào)域名注冊(cè)品牌網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)