有各种各样的线索:男人和女人.两者都想使用数量为BATHROOM_SIZE的相同资源. 5条规则:
>在发出信号需要使用资源之后,每个线程都应该等到他能够使用它.
>当多个BATHOOM_SIZE线程同时使用资源时,防止出现这种情况.
>防止女人和男人同时使用浴室.
>线程应同时使用资源.如果有一种类型的线程很多,那么BATHROOM_SIZE线程应该使用资源.
>防止饥饿.
结果
效劳于:
1女,1人,5女,5人
失败:
5women1men,5men1women,2men2women,5men5women.
自从周一以来我一直在尝试让它成功,现在我的想法已经用完了.
码
所以我的任务是编写实现BathroomInterface的Bathroom.java类:
public interface BathroomInterface { public static final int BATHROOM_SIZE = 3; //3 is just example void manEnter(); void manExit(); void womanEnter(); void womanExit(); }
在系统中有许多男人和女人的线程像这样工作:
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(); }
我也有Bathroom.java类的方案,我必须扩展:
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(); } }
这是我到目前为止所做的:
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(); } } } }
解决方法
一把锁:
private Lock lock = new ReentrantLock();
附加到锁上的2个条件或队列:
private Condition womenWaitingQueue = lock.newCondition(); private Condition menWaitingQueue = lock.newCondition();
2个计数器知道有多少人正在等待,2个计数器知道有多少人正在使用:
private int womenWaitingN = 0; private int menWaitingN = 0; private int womenUsingN = 0; private int menUsingN = 0;
当然还有资源数量:
private final int BATHROOM_CAPACITY = 5; private int free_resources = BATHROOM_CAPACITY;
这里最重要的是防止饥饿,如果有女人在等待和反之,不允许任何男人进入浴室.
因此,条件是,如果一个男人想进入浴室,它必须检查浴室是否至少有一个免费点(使用免费资源),如果浴室里有女性(使用womenUsingN).如果不满足这两个条件中的任何一个,那么该人必须等待(使用menWaitingQueue):
menWaitingQueue.await();
当一个男人离开浴室时,必须检查是否有女性在等待(女性等待N),如果有,她们会得到通知:
womanWaitingQueue.signal();
由于menUsingN柜台,女性发出信号,直到浴室里没有男人才能进入.如果没有女性在等待,那么可以发信号通知男性进入浴室.这可以防止饥饿,因为优先考虑异性(如果等待).
最后一点是,每个函数必须在每个进入/退出函数的开头/结尾锁定/解锁锁.
lock.lock(); lock.unlock();
我认为通过这些新信息,您将能够自己完成这些功能.祝好运!