匿名使用者
匿名使用者 發問時間: 娛樂與音樂音樂其他:音樂 · 9 年前

wait 和 notify 的問題

//start 執行 run 方法然後執行eat

//第一次是true 所以wait(); notify();

//put(); 也是true 不會wait();沒交出鎖 notify();

// 這樣eat(); 照理說就不會執行 因為沒有鎖!!

// 接下來會怎麼跑呢??

//我的程式是ok的 只會我邏輯不懂請幫我解惑 這問題我想了一小時@@

class Cookies{

private int cookiesNO; //餅乾編號

private boolean empty =true; //表是盤子是空的

public synchronized void put(int cNo){ //主人放餅乾的方法

while(!empty){

try{

wait(); //盤子不是空的,則主人進入等待狀態

} catch(InterruptedException e){}

}

System.out.println("主人放了第" + cNo + "塊餅乾");

this.cookiesNO =cNo;

empty = false; //盤子不是空的,意味著盤子內有餅乾

notify(); //呼叫小白狗來吃餅乾

}

public synchronized void eat(int cNo){ //小白狗吃餅乾的方法

while(empty){

try{

wait(); //盤子是空的,則小白狗進入等待狀態

}catch(InterruptedException e){}

}

empty = true; //盤子是空的

notify(); //叫主人

System.out.println("小白狗吃了第 " + cNo + "塊餅乾");

}

}class Put implements Runnable{

Cookies cookies;

Put(Cookies cookies){

this.cookies = cookies;

}

public void run(){

for(int i = 1 ; i<= 10 ;i++){

cookies.put(i);

}

}

}

class Eat implements Runnable{

Cookies cookies;

Eat(Cookies cookies){

this.cookies = cookies;

}

public void run(){

for(int i = 1 ; i<= 10 ; i ++){

cookies.eat(i);

}

}

}

public class Three {

public static void main(String[] args){

Cookies cookies = new Cookies();

Put put = new Put(cookies); //主人放餅乾

Eat eat = new Eat(cookies); //小白狗吃餅乾

Thread dog = new Thread(eat); //小白狗執行緒

Thread master = new Thread(put); //主人執行緒

dog.start();

master.start();

}

}

1.

已更新項目:

早上睡起來突然有靈感

//start 執行 run 方法然後執行eat

//第一次是true 所以wait(); notify();

//put(); 也是true 不會wait();沒交出鎖 notify();

// 這樣eat(); 照理說就不會執行 因為沒有鎖!!

<<插入>>eat()不會跑 所以又跑put() 發現在false

就進入wait()

就這樣重複循環到結束

不知道你們有沒有懂我的意思

// 接下來會怎麼跑呢??

2 個已更新項目:

而在第二個 while旗標鎖住的方法==>小狗吃餅乾的方法(eat)

在判斷 ==> empty = true; //盤子中餅乾吃完ㄌ空ㄌ

notify(); ==> (eat方法)釋放旗標 //呼叫主人放餅乾方法(put)喚醒 進入Runnable的區域開始等電腦排程 然後等到runing 開始運作

我的問題就卡在這裡

第一次進來eat(){

empty = false

不會執行while(empty){

wait(); //因不會執行,所以不會丟出鎖

}

}

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑是註解↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

3 個已更新項目:

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓是問題↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

empty = true; //盤子中餅乾吃完ㄌ空ㄌ

notify() 呼叫其他執行緒 而不會丟出鎖 //會丟出鎖的是wait()

換put()執行 而沒有鎖

又輪到eat()

是不是因為又執行了一次

eat()

while(empty){ //發現是true

wait(); //這時後才丟出鎖

}

現在put才有使用權!!

4 個已更新項目:

真的很巧,我們是同一個老師教的

對阿!!!段老師教得很好

老師上課

不會點名 也不會記同學的名子

這樣要怎麼幫你向老師問好!?

我覺得我真的很幸運呢XD"

現在,在學JAVA遇到好老師

學英文也遇到好老師

又加上遇上了你

很有耐心的講解

因為我覺得JAVA這種東西

很少人會那麼用心的講解(不熟的人)

5 個已更新項目:

沒到那麼晚你還沒睡!!

早點休息也對身體比較好

謝謝你 我總算瞭解了

尤其是你後面的補充

我相信這題會永身難忘的

假如eat();

都一直呼叫不到wait();

而呼叫notify(); 會怎樣?

是不是 會一直跑eat方法!!

而照成死結!?

(晚安)

6 個已更新項目:

你現在人還在桃園嗎!?

要不要我跟你說上課時間

這樣你可以去看看他XD

7 個已更新項目:

1 個解答

評分
  • 9 年前
    最佳解答

    哈~~看來出自同一個老師教的~~幫我向老師請安阿

    你程式中註解有些不太對

    在第一個迴圈旗標鎖住的方法==>主人放餅乾的方法(put)

    在判斷 empty = false;時表示盤子餅乾吃完ㄌ~~主人開始再放餅乾

    然後notify(); ==>釋放出旗標 //呼叫小白狗來吃餅乾方法(也就是釋放旗標put的執行緒~~呼叫eat 執行緒~~叫醒eat執行緒可以進入Runnable的區域開始等帶電腦排程等到排到時進入runing開始用作

    而在第二個 while旗標鎖住的方法==>小狗吃餅乾的方法(eat)

    在判斷 ==> empty = true; //盤子中餅乾吃完ㄌ空ㄌ

    notify(); ==> (eat方法)釋放旗標 //呼叫主人放餅乾方法(put)喚醒 進入Runnable的區域開始等電腦排程 然後等到runing 開始運作

    所以說在put的方法判斷為 false 進入等待池(wait pool)而喚醒 eat() 進入Runnable等待執行排程在開始 run()

    而eat() 在判斷為 true 時~~進入等待池 而喚醒put()

    進入Runnable 區等待CPU排程進入runing 開始run

    下方圖解為執行緒的執行及非執行狀態或是等待,銷毀狀態等示意圖解

    圖片參考:http://imgcld.yimg.com/8/n/AE02886810/o/1512022609...

    2012-02-27 20:04:50 補充:

    如你也是段老師的學生~~幫我請個安~~很遺憾我沒再上的下一階段的課,但真感謝他教得很詳細讓我這個什麼系都不是的老頑童在初階能很透徹的學習到java的基礎~順利100% 通過SCWCD證照考!! 幫我替他說感恩喲!!

    2012-02-27 22:38:08 補充:

    你的問題卡在~~~一直老是繞在eat()與 put()的判斷

    其實這是兩個不同迴圈的方法~~

    第一個迴圈條件是設定 while(!empty)==>主人放餅乾的時機

    是如是true 時主人put 是沒有動作是等待狀況(也就是處於 wait()狀態)而印出

    ("主人放了第" + cNo + "塊餅乾");的顯示

    然後當判斷式符合ㄌwhile中的布林值時==>while(!empty) 也就是==>empty = false; 時才會釋放旗標資源 喚醒 eat() 去等待CPU分配行程開始run()的運作

    2012-02-27 22:38:16 補充:

    而其下的eat()的迴圈判斷條件是 while(empty) ==>也就是布林值判斷要是 true 時eat()的方法才會釋放旗標資源 喚醒put()等待CPU分配行程開始run()的運作

    也就是說在eat()==>狗狗在吃的盤子還沒是空的(flase)時是處於wait的狀態,而要等布林值符合判斷是empty = true; 才會釋放旗標資源來喚醒put()

    2012-02-27 22:41:51 補充:

    所以兩個方法中的丟出鎖定旗標時機都是在符和布林值判斷時運作ㄌnotify(); 時才丟出鎖定旗標

    2012-02-27 22:55:04 補充:

    我姓范~~你跟老師說他一定記的~~因為我是學java的學生中最老的且不是資工資管系~~只有讀到高中半年~~且6年前是電腦白癡他都知道~~我也是班上最愛問問題的學生所以你跟他說他會記的~~他還送過他的書給我~~猛虎出閘

    2012-02-27 23:31:17 補充:

    大概前面回答時沒說清楚及逗點沒仔細標示讓你誤解ㄌ

    應該說在put的方法判斷為 true 進入等待池(wait pool)而在這要逗點,註明當符合判斷為 flase時喚醒 eat() 進入Runnable等待執行排程在開始 run()

    eat() 在判斷為flase 時~~進入等待池而在這要逗點,註明當符合判斷為true時 而喚醒put()

    進入Runnable 區等待CPU排程進入runing 開始run

    2012-02-28 00:01:57 補充:

    你可以跟老師說前年在桃園認證的學生,java初階結束前我有寫出求質數的程式~~他說他教的學生在初階能寫出這程式的不超過五個~~還有很愛打扮的美美的老女人他一定記的

    2012-02-28 01:45:06 補充:

    對 執行緒程式如沒設定好不單會造成死結也會依值跑引起記憶體不夠的 執行緒程式如沒設定好不單會造成死結也常會一直 run 引起記憶體不夠的Erro的嚴重錯誤

    參考資料: 加菲貓, 加菲貓, 加菲貓, 加菲貓
還有問題?馬上發問,尋求解答。