Could I ask you to evaluate my solution to Unisex Bathroom Problem?
Problem description
An office has a bathroom that can be used by both men and women, but not both at the same time. If a man is in the bathroom, other men may enter, but any women wishing to use the bathroom should wait for it to be empty. If a woman is in the bathroom, other women may enter, but any men wishing to use the bathroom should wait it to be empty. Each person (man or woman) will spend some time using the bathroom.
Task
Design and implement a concurrent solution to the problem. The program should show when a person (man or woman) enters or exits the bathroom; as well as how many people (men or women) are in the bathroom at the moment. Because it is a space of relatively small size, the bathroom has a limiting capacity of persons C (provided as input via the command line or prefixed as a constant value) that can use it at the same time and the time that each person passes in the bathroom is random and different to each program execution.
My solution
I tried to also solve a starvation issue and I think I succeeded.
Besides all of that, what is the necessity of semaphores that the problem is related to? Why can't size
be simply compared to capacity
as I did?
public class Bathroom {
private String inUseBy;
private int size;
private final int capacity;
private final Lock lock = new ReentrantLock();
private final Condition man = lock.newCondition();
private final Condition woman = lock.newCondition();
public Bathroom(final int capacity, final int size) {
this.capacity = capacity;
this.size = size;
inUseBy = "";
}
public void enter(final String sex) throws InterruptedException {
lock.lock();
try {
while (size == capacity || (size > 0 && !sex.equals(inUseBy))) {
if (sex.equals("M")) {
man.await();
} else {
woman.await();
}
}
if (size == 0) {
inUseBy = sex;
}
size++;
} finally {
lock.unlock();
}
System.out.println(sex + " using bathroom. Current employees in bathroom = " + size);
Thread.sleep(10000);
System.out.println(sex + " done using bathroom");
lock.lock();
try {
size--;
if (size == 0) {
if (sex.equals("M")) {
woman.signalAll();
} else {
man.signalAll();
}
} else {
if (sex.equals("M")) {
man.signal();
} else {
woman.signal();
}
}
} finally {
lock.unlock();
}
}
}