想象一下,有一个按摩师,他有自己的沙龙。他整天都在睡觉,直到顾客进入沙龙并叫醒他。
客户在按摩时正在睡觉。当按摩师完成后,他会唤醒顾客并获得他的服务报酬。
客户离开沙龙。按摩师进入候诊室寻找另一个等待(睡觉)的顾客。如果没有任何按摩师再次上床睡觉。
使用线程时这是一个有趣的情况。
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 :(得分:0)
你在描述Dijkstra的睡眠理发师问题,但是有按摩沙龙而不是理发店。但解决方案仍然相同,可以在此处找到:http://en.wikipedia.org/wiki/Sleeping_barber_problem#Solution
答案 1 :(得分:0)
您可以使用名为NotSleeping的公平Semaphore。
只要客户没有进入轿车,它就会持有NotSleeping。当客户进来时,它会释放信号量,这会唤醒按摩师尝试抓住NotSleeping的线程。发布后,客户在按摩期间尝试再次按住NotSleeping。
完成后,Masseur发布NotSleeping,客户再次对其进行评分。男按摩师,试图再次举行NotSleeping,直到顾客进来。等等......