如何正确同步此模型?

时间:2011-05-09 05:43:57

标签: java multithreading

想象一下,有一个按摩师,他有自己的沙龙。他整天都在睡觉,直到顾客进入沙龙并叫醒他。

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

客户离开沙龙。

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

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

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++;
    }
}

2 个答案:

答案 0 :(得分:0)

你在描述Dijkstra的睡眠理发师问题,但是有按摩沙龙而不是理发店。但解决方案仍然相同,可以在此处找到:http://en.wikipedia.org/wiki/Sleeping_barber_problem#Solution

答案 1 :(得分:0)

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

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

完成后,Masseur发布NotSleeping,客户再次对其进行评分。男按摩师,试图再次举行NotSleeping,直到顾客进来。等等......