Java unisex bathroom
java, multithreading, semaphore
Solution
Actually this exercise is done using a monitor, and not a semaphore. What you're doing is mostly fine, you're missing the conditions. So, in your bathroom class, declare:
a lock:
private Lock lock = new ReentrantLock();
2 conditions or queues, attached to your lock:
private Condition womenWaitingQueue = lock.newCondition();
private Condition menWaitingQueue = lock.newCondition();
2 counters to know how many are waiting, and 2 to know how many are using:
private int womenWaitingN = 0;
private int menWaitingN = 0;
private int womenUsingN = 0;
private int menUsingN = 0;
and of course, the number of resources:
private final int BATHROOM_CAPACITY = 5;
private int free_resources = BATHROOM_CAPACITY;
all 4 functions were here, but removed because of the homework tag
The important thing here is to prevent starvation, by not allowing any men to enter the bathroom if there are women waiting and viceversa.
so, conditions are that if a man wants to enter to the bathroom, it has to check if the bathroom has at least 1 free spot (using free resources) and if there are women in the bathroom (using womenUsingN). If any of these 2 conditions are not met, the man must wait(using the menWaitingQueue):
menWaitingQueue.await();
when a man leaves the bathroom, it has to check if there are any women waiting (womenWaitingN), if there are, they get notified:
womanWaitingQueue.signal();
because of the menUsingN counter, women signaled by this wont be able to enter until there are no men in the bathroom. If there are no women waiting, then a man can be signaled to enter the bathroom. This prevents starvation because priority is given to the opposite sex (if waiting).
The last thing, is that every function must lock/unlock the lock at beginning/end of each enter/exit function.
lock.lock();
lock.unlock();
I think with this new information you'll be able to make the functions on your own. Good luck!
Problem
I have to solve this problem using Java semaphores, but I have no idea how, and I cannot find any related Java materials. This is how it goes: There are to kinds of threads: men and women. Both wants to use same resources which quantity is BATHROOM_SIZE. 5 rules: - Every thread, after signaling need of using resource, should wait until he will be able to use it. - Prevent situation, when more than BATHOOM_SIZE threads is using resource concurrently. - Prevent woman and man use bathoom in the same time. - Threads should use resources concurrently. If there are many threads of one type, up to BATHROOM_SIZE threads should use resource. - Prevent starvation. Results Works for: 1woman, 1man, 5women, 5men Fails for: 5women1men, 5men1women, 2men2women, 5men5women. I've been trying to make it work since Monday and now I've run out of ideas. Code So my task is to write Bathroom.java class which implements BathroomInterface: ``` public interface BathroomInterface { public static final int BATHROOM_SIZE = 3; //3 is just example void manEnter(); void manExit(); void womanEnter(); void womanExit(); } ``` In system there are a number of man and woman threads which work like this: ``` for(int i = 0; i < n; i++) { bathroom.manEnter(); //uses bathroom random amount of time bathroom.manExit(); } for(int i = 0; i < m; i++) { bathroom.womanEnter(); //uses bathroom random amount of time bathroom.womanExit(); } ``` I also have scheme of Bathroom.java class, I have to extend: ``` import java.util.concurrent.Semaphore; public class Bathroom implements BathroomInterface { private Semaphore mutex = new Semaphore(1, true); public void womanEnter() { mutex.acquireUninterruptibly(); } public void womanExit() { mutex.release(); } public void manEnter() { mutex.acquireUninterruptibly(); } public void manExit() { mutex.release(); } } ``` This is what I made so far: ``` import java.util.concurrent.Semaphore; public class Bathroom implements BathroomInterface { int manW=0, manU=0, womanW=0, womanU=0; //*U-using, *W-waiting private Semaphore mutex = new Semaphore(1, false); public void womanEnter() { womanW++; StateChange(); } public void womanExit() { womanU--; mutex.release(); StateChange(); } public void manEnter(){ manW++; StateChange(); } public void manExit() { manU--; mutex.release(); StateChange(); } void StateChange() { if(womanU==0 && manU==0) { if(manW>womanW) { while(manW>0 && manU<BATHROOM_SIZE) { manW--; manU++; mutex.acquireUninterruptibly(); } } else { while(womanW>0 && womanU<BATHROOM_SIZE) { womanW--; womanU++; mutex.acquireUninterruptibly(); } } } if(womanU==0 && manU<BATHROOM_SIZE) { while(manW>0 && manU<BATHROOM_SIZE) { manW--; manU++; mutex.acquireUninterruptibly(); } } if(manU==0 && womanU<BATHROOM_SIZE) { while(womanW>0 && womanU<BATHROOM_SIZE) { womanW--; womanU++; mutex.acquireUninterruptibly(); } } } } ```