2011-05-09 44 views
0

想象一下,有一個按摩師,他有自己的沙龍。他整天都在睡覺,直到一位顧客進入沙龍並喚醒他。如何正確同步此模型?

顧客正在睡覺,而他得到按摩。當按摩師完成時,他會喚醒顧客併爲他的服務獲得報酬。

顧客離開沙龍。

按摩師進入候診室尋找另一個等待(睡覺)的顧客。如果沒有任何按摩師再次上牀睡覺。

使用線程時,這是一個有趣的情況。

public class Aufg1{ 
    public static void main(String args[]){ 
     MassageSalon ms = new MassageSalon(); 
     Customer c = new Customer(ms); 
     Masseur m = new Masseur(ms); 
     m.start(); c.start(); 
    } 
} 

Masseur.java

public class Masseur extends Thread{ 

    final MassageSalon salon; 

    public Masseur(MassageSalon pSalon){ 
     salon = pSalon; 
    } 

    public void run(){ 
     while(true){ 
      salon.getNextCustomer(); 
      salon.finishedMassage(); 
     } 
    } 
} 

Customer.java

public class Customer extends Thread{ 

    final MassageSalon salon; 

    public Customer(MassageSalon pSalon){ 
     salon = pSalon; 
    } 

    public void run(){ 
     while(true){ 
      salon.getMassage(); 
     } 
    } 
} 

我有一個類MassageSalon。代碼與我剛剛提到的幾乎一樣。

現在我想用wait(), notify(), notifyAll()確保一切正常,就像我提到的那樣。我已經編輯了MassageSalon類並添加了wait(),notify()方法。

您認爲wait()和notify()的位置是否正確?運行此代碼時,不會調用finishedMassage方法。爲什麼?

public class MassageSalon { 
    private int customerOnCouch = 0; 
    private int customerPaid = 0; 
    private int masseurAvailable = 0; 
    private int masseurBusy = 0; 
    private int masseurDone = 0; 
    private int masseurClose = 0; 


    public synchronized void getNextCustomer() { 

     while(masseurAvailable != masseurClose){ 
      try{ 
       System.out.println("waiting for masseur..."); 
       wait(); 
      }catch(InterruptedException e){ 
       System.out.println(e); 
      } 
     } 

     //masseur is available to handle a new customer 

     System.out.println("masseur is available to handle a new customer"); 

     masseurAvailable++; 

     while(customerOnCouch == customerPaid){ 
      try{ 
       System.out.println("waiting for customer..."); 
       wait(); 
      }catch(InterruptedException e){ 
       System.out.println(e); 
      } 
     } 

     //and is busy as soon as a new customers takes his couch 

     System.out.println("and is busy as soon as a new customers takes his couch"); 

     masseurBusy++; 
    } 

    public synchronized void finishedMassage() { 
     //eventually the masseur finishes the massage 

     System.out.println("eventually the masseur finishes the massage"); 

     masseurDone++; 

     notify(); 

     //and closes the deal as soon as the customer paid 

     System.out.println("and closes the deal as soon as the customer paid"); 

     masseurClose++; 
    } 

    public synchronized void getMassage() { 
     //customer takes a couch 

     System.out.println("customer takes a couch"); 

     customerOnCouch++; 

     notify(); 

     while(masseurBusy != masseurDone){ 
      try{ 
       System.out.println("waiting to finish massage"); 
       wait(); 
      }catch(InterruptedException e){ 
       System.out.println(e); 
      } 
     } 

     //and pays for the massage after it 

     System.out.println("and pays for the massage after it"); 

     customerPaid++; 
    } 
} 
+0

看起來像我的作業... – Rom1 2011-05-09 05:51:37

+4

@ Rom1:是的,它是[Dijkstra的睡眠理髮師問題](http:// en。 wikipedia.org/wiki/Sleeping_barber_problem)。 – 2011-05-09 05:53:27

回答

0

你正在描述迪傑斯特拉的睡眠理髮師問題,但與按摩沙龍,而不是理髮店。儘管如此,解決方案仍然相同:http://en.wikipedia.org/wiki/Sleeping_barber_problem#Solution

+0

以及它不完全相同。我只想知道在上面的代碼中等待的位置,notfiy和notifyAll有互斥。 – 2011-05-09 06:06:59

+0

@ArtWorkAD。很多事情都沒有了。您需要創建線程和某種客戶隊列。 – Kaj 2011-05-09 06:09:30

0

您可以使用名爲NotSleeping的公平的Semaphore

只要客戶沒有進入轎車,它就會持有NotSleeping。當顧客進來時,它釋放信號量,這喚醒了按摩師試圖搶NotSleeping的線程。發佈後,客戶在按摩過程中會嘗試再次按住NotSleeping。

完成後,Masseur發佈NotSleeping,由客戶再次抓取。 Masseur,試圖再次舉辦NotSleeping,直到顧客進來。等等......