2017-03-12 35 views
-2

嗯,我是第二學期的學生,現在我們正在通過線程。我主要得到它,但我的一個練習中有一些是關閉的,我不能理解它。線程練習 - 幫我理解

「在一家麪包店裏,當你到達商店時,你經常需要拿一個數字,然後等到你的 轉(用正確的數字)。」 我想複製粘貼顯示器中的方法,我認爲問題可能是。

private NumberDispenser(){ 
    nextNoToTake=1; 
    nextNoToServe=0; 
} 

public static NumberDispenser accessDispenser(){ 
    if(theOne == null){ 
     theOne = new NumberDispenser(); 
    } 
    return theOne; 
} 


@Override 
public synchronized void takeNextNumber() { 
    int currNo = nextNoToTake; 
    nextNoToTake++; 
    notifyAll(); 
    System.out.println("No:"+currNo+" has been taken|nextNoToServe:"+nextNoToServe); 
    while(currNo != nextNoToServe) 
     {try { 
      wait(); 
     } catch (InterruptedException e) {} 
     } 
    System.out.println("No:"+currNo+" has been served"); 
    notify(); 
} 

@Override 
public synchronized int nextCustomer() {//Serves the current customer and goes to the next one 
    System.out.println("Clerk is ready to deal with a new customer"); 

    while((nextNoToServe)>=nextNoToTake-1) 
     try { 
      wait(); 
     } catch (InterruptedException e) {} 
    nextNoToServe++; 
    notifyAll(); 
    System.out.println("Now serving No:"+(nextNoToServe)); 

    return nextNoToServe; 
} 

這是監視器類。對於客戶和祕書還有兩個,還有一個用於測試。客戶類有Thread.sleep模擬瀏覽時間,然後進入dispenser.takeNextNumber();之後它應該完成,並且負責它的線程應該自己死掉(在主類中).Clerk循環分發器.nextCustomer( )無限延遲。主要方法在單獨的for循環中創建一些客戶及其線程,以及一些職員和他們的線程。

/////這是從需求粘貼的副本。 客戶到達和店員服務由線程模擬。

實現監視器實現接口TakeANumber的類NumberDispencer。 提示:你可以定義兩個實例變量 private int nextNumberToTake = 1; private int nextNumberToServe = 1;

實現兩個線程類: 它模擬客戶採取了一系列與被服務 模擬店員服務,即得到下一個客戶號碼,然後讓 服務線程類的線程類。

用主要方法實現一個類來模擬麪包店,兩名服務文員和十名客戶。 /////

我幾乎修復了代碼。問題在於while循環的情況。現在它幾乎按照預期工作,但它跳過了第一個客戶。只有第一個客戶被跳過了,那麼這一切都應該如何。

console output

+0

此程序的預期行爲是什麼,您遇到的行爲是什麼?根據守則判斷,僵局是可能的。 – Soronbe

+0

你的問題仍然不清楚。你想了解上面的代碼。或者你想在演習中使用這些代碼。 –

+0

無論你的問題可能,但takeNextNumber()永遠不會調用notify()或notifyAll()?你有沒有想過爲什麼?因爲通過調用wait(),你基本上是通知其他線程掛起一段時間,而那些**等待**從來沒有應得的notify()或notifyAll()? – ShayHaned

回答

0

我可以看到一個地方壞了。

提示:假設有一個服務器和一個客戶,服務器在客戶到達之前調用nextCustomer()。顧客到達時會叫醒它什麼?

此外,這種說法是黑客。

if (nextNoToServe == 0) 
    nextNoToServe = 1; 

這應該通過初始化實例變量來處理適當的值;例如在構造函數中。

+0

是的,我已經這樣做了,試圖更好地理解它。 我已經把一個單一的職員和一個客戶。他們做事的順序也搞砸了。我已經刪除了所有線程睡眠以「模擬」它們的工作,並且將嘗試找到什麼是錯誤的等待,並通知零件 –

+0

我知道,當職員準備好與顧客打交道時,在顧客來之前(自然地)顧客立即來服務。所以計數器的位置是錯誤的,或者它是按照它應該做的,我只是搞糟了Sysouts的位置。 –

+0

感謝您的提示,我已經看到並糾正了一個錯誤,但現在它只是跳過第一個客戶。我會繼續尋找,但你一直很有幫助,謝謝:) –