Reputation: 70466
I have realized some logic using integers
import java.util.concurrent.locks.*;
public class MassageSalon implements Salon{
//I want to transform this into bool
private int customerOnCouch = 0;
private int customerPaid = 0;
private int masseurAvailable = 0;
private int masseurBusy = 0;
private int masseurDone = 0;
private int masseurClose = 0;
Lock lock = new ReentrantLock();
Condition sleep = lock.newCondition();
public void getNextCustomer() throws InterruptedException{
lock.lock();
masseurAvailable++;
System.out.println("masseur is available to handle a new customer");
sleep.signalAll();
//wait for next customer
while(customerOnCouch < masseurAvailable){
System.out.println("masseur sleeps");
sleep.await();
System.out.println("masseur wakes up");
}
//customer takes couch, masseur busy
masseurBusy++;
System.out.println("masseur busy");
lock.unlock();
}
public void finishedMassage() throws InterruptedException{
lock.lock();
//eventually the masseur finishes the massage
System.out.println("eventually the masseur finishes the massage");
masseurDone++;
sleep.signalAll();
//and closes the deal as soon as the customer paid
while(masseurDone > customerPaid){
System.out.println("wait for payment");
sleep.await();
}
System.out.println("and closes the deal as soon as the customer paid");
masseurClose++;
lock.unlock();
}
public void getMassage(int customerId) throws InterruptedException{
lock.lock();
while(customerOnCouch > masseurClose){
System.out.println(customerId + " on couch waiting");
sleep.await();
}
//takes couch
customerOnCouch++;
System.out.println(customerId + " on couch");
sleep.signalAll();
while(masseurDone <= customerPaid){
System.out.println("customer " + customerId + " sleeps");
sleep.await();
}
System.out.println("customer " + customerId + " wakes up");
customerPaid++;
System.out.println("customer " + customerId + " payes");
sleep.signalAll();
lock.unlock();
}
}
This logic uses integers. Since this is a threaded context I want to use booleans now instead of integers to avoid overflows.
So I came up with this. However this does not the same as the example above. What would be the right transformation?
import java.util.concurrent.locks.*;
public class MassageSalon implements Salon{
private boolean customerOnCouch = false;
private boolean customerPaid = false;
private boolean masseurAvailable = false;
private boolean masseurBusy = false;
private boolean masseurDone = false;
private boolean masseurClose = false;
Lock lock = new ReentrantLock();
Condition sleep = lock.newCondition();
public void getNextCustomer() throws InterruptedException{
lock.lock();
masseurAvailable = true;
customerOnCouch = false;
masseurBusy = false;
customerPaid = false;
masseurDone = false;
masseurClose = false;
System.out.println("masseur is available to handle a new customer");
sleep.signalAll();
//wait for next customer
while(!customerOnCouch && masseurAvailable){
System.out.println("masseur sleeps");
sleep.await();
System.out.println("masseur wakes up");
}
//neuer kunde nimmt platz, masseur ist busy
masseurBusy = true;
System.out.println("masseur busy");
lock.unlock();
}
public void finishedMassage() throws InterruptedException{
lock.lock();
//eventually the masseur finishes the massage
System.out.println("eventually the masseur finishes the massage");
masseurDone = true;
sleep.signalAll();
//and closes the deal as soon as the customer paid
while(masseurDone && !customerPaid){
System.out.println("wait for payment");
sleep.await();
}
System.out.println("and closes the deal as soon as the customer paid");
masseurClose = true;
lock.unlock();
}
public void getMassage(int customerId) throws InterruptedException{
lock.lock();
while(customerOnCouch && !masseurClose){
System.out.println(customerId + " on couch waiting");
sleep.await();
}
//takes couch
customerOnCouch = true;
System.out.println(customerId + " on couch");
sleep.signalAll();
while(masseurDone && !customerPaid){
System.out.println("customer " + customerId + " sleeps");
sleep.await();
}
System.out.println("customer " + customerId + " wakes up");
customerPaid = true;
System.out.println("customer " + customerId + " payes");
sleep.signalAll();
lock.unlock();
}
}
Upvotes: 0
Views: 243
Reputation: 55937
I'm not sure that you have a valid "model" using either integers or booleans.
You are modelling some states, and for each state you use multiple counters or booleans. To illustrate: the masseuse has four booleans which can be set independently, and yet many combinations are meaningless:
Busy == true and Done == true?
Instead model the state of the masseuse using an enum, with values such as Available and Working.
Have a separate class for the Masseuse with methods such as
boolean isAvailable();
void startWorking();
void stopWorking();
Your customers, I think you should model in two parts: a single Customer class, which has states such as Waiting, OnCouch, NeedToPay, Complete. and separately a queue to hold the customers in Waiting state.
In response to your determination to use booleans:
To make this work I would still encapsulate the state information in Mansseuse and Customer objects. Then I would consider each state transition: for example from working to stopped, for that transition have a method which sets the appropriate booleans. In this way you get a clear picture of the effect of each transition, and presumably will notice that some flags need to be unset in certain situations.
As a learning point you should consider how brittle your solution is - I predict that should you ever need to add a few more states in the life-cycle your code will be unmaintainable, and probably already is quite hard to understand for anybody other than yourself. You're finding this hard to reason about because your representation (multiple booleans) doesn't really fit the problem domain - a set of state transitions.
Upvotes: 1