如何正确同步此模型?

问题描述:

想象一下,有一个按摩师,他有自己的沙龙。他整天都在睡觉,直到一位顾客进入沙龙并唤醒他。如何正确同步此模型?

顾客正在睡觉,而他得到按摩。当按摩师完成时,他会唤醒顾客并为他的服务获得报酬。

顾客离开沙龙。

按摩师进入候诊室寻找另一个等待(睡觉)的顾客。如果没有任何按摩师再次上床睡觉。

使用线程时,这是一个有趣的情况。

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

你正在描述迪杰斯特拉的睡眠理发师问题,但与按摩沙龙,而不是理发店。尽管如此,解决方案仍然相同: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

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

只要客户没有进入轿车,它就会持有NotSleeping。当顾客进来时,它释放信号量,这唤醒了按摩师试图抢NotSleeping的线程。发布后,客户在按摩过程中会尝试再次按住NotSleeping。

完成后,Masseur发布NotSleeping,由客户再次抓取。 Masseur,试图再次举办NotSleeping,直到顾客进来。等等......