加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java男女皆宜的卫生间

发布时间:2020-05-24 23:31:45 所属栏目:Java 来源:互联网
导读:我必须使用 Java信号量解决这个问题,但我不知道如何,我找不到任何相关的Java资料.这是怎么回事: 有各种各样的线索:男人和女人.两者都想使用数量为BATHROOM_SIZE的相同资源. 5条规则: 在发出信号需要使用资源之后,每个线程都应该等到他能够使用它. 当多个BA

我必须使用 Java信号量解决这个问题,但我不知道如何,我找不到任何相关的Java资料.这是怎么回事:

有各种各样的线索:男人和女人.两者都想使用数量为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;

所有4个功能都在这里,但由于家庭作业标签被删除

这里最重要的是防止饥饿,如果有女人在等待和反之,不允许任何男人进入浴室.

因此,条件是,如果一个男人想进入浴室,它必须检查浴室是否至少有一个免费点(使用免费资源),如果浴室里有女性(使用womenUsingN).如果不满足这两个条件中的任何一个,那么该人必须等待(使用menWaitingQueue):

menWaitingQueue.await();

当一个男人离开浴室时,必须检查是否有女性在等待(女性等待N),如果有,她们会得到通知:

womanWaitingQueue.signal();

由于menUsingN柜台,女性发出信号,直到浴室里没有男人才能进入.如果没有女性在等待,那么可以发信号通知男性进入浴室.这可以防止饥饿,因为优先考虑异性(如果等待).

最后一点是,每个函数必须在每个进入/退出函数的开头/结尾锁定/解锁锁.

lock.lock();
lock.unlock();

我认为通过这些新信息,您将能够自己完成这些功能.祝好运!

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读