#java
#java
Вопрос:
Я реализовал некоторую логику, используя целые числа
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();
}
}
В этой логике используются целые числа. Поскольку это многопоточный контекст, я хочу теперь использовать логические значения вместо целых чисел, чтобы избежать переполнений.
Итак, я придумал это. Однако это не то же самое, что в примере выше. Каким было бы правильное преобразование?
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 amp;amp; 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 amp;amp; !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 amp;amp; !masseurClose){
System.out.println(customerId " on couch waiting");
sleep.await();
}
//takes couch
customerOnCouch = true;
System.out.println(customerId " on couch");
sleep.signalAll();
while(masseurDone amp;amp; !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();
}
}
Комментарии:
1. Помогло бы, если бы все было на английском.
Ответ №1:
Я не уверен, что у вас есть допустимая «модель», использующая либо целые числа, либо логические значения.
Вы моделируете некоторые состояния, и для каждого состояния вы используете несколько счетчиков или логических значений. Для иллюстрации: у masseuse есть четыре логических значения, которые могут быть установлены независимо, и все же многие комбинации бессмысленны:
Busy == true and Done == true?
Вместо этого смоделируйте состояние массажистки, используя перечисление, с такими значениями, как Доступно и работает.
Создайте отдельный класс для массажиста с такими методами, как
boolean isAvailable();
void startWorking();
void stopWorking();
Я думаю, что вы должны моделировать своих клиентов из двух частей: единый класс Customer, который имеет такие состояния, как ожидание, OnCouch, NeedToPay, Complete. и отдельно очередь для удержания клиентов в состоянии ожидания.
В ответ на ваше решение использовать логические значения:
Чтобы это сработало, я бы все равно инкапсулировал информацию о состоянии в объекты Mansseuse и Customer. Затем я бы рассмотрел каждый переход состояния: например, от working к stopped, для этого перехода есть метод, который устанавливает соответствующие логические значения. Таким образом, вы получите четкое представление об эффекте каждого перехода и, предположительно, заметите, что некоторые флаги необходимо снимать в определенных ситуациях.
В качестве учебного пункта вам следует учесть, насколько хрупким является ваше решение — я предсказываю, что если вам когда-нибудь понадобится добавить еще несколько состояний в жизненный цикл, ваш код будет неуправляем, и, вероятно, его уже довольно сложно понять кому-либо, кроме вас самих. Вам трудно рассуждать об этом, потому что ваше представление (несколько логических значений) на самом деле не соответствует проблемной области — набору переходов состояний.
Комментарии:
1. Спасибо за ответ, но на самом деле я хочу использовать логические значения (я должен: D). Я тоже думал о бессмысленных комбинациях, я попробовал несколько вещей, но у меня все еще нет рабочей модели. Целочисленная модель работает нормально.
2. Не совсем, я просто практикую для себя