题目要求:
假设一个大学为了卖弄其政治上的正确性,准备把美国最高法院的信条“平等但隔离其本身就是不平等”既运用在种族上也运用在性别上,从而结束校园内长期使用的浴室按性别隔离的做法。但是,为了迁就传统习惯,学校颁布法令:当有一个女生在浴室里,那么其他女生可以进入,但是男生不行,反之亦然。在每个浴室的门上有一个滑动指示符号,表示当前处于以下三种可能状态之一:
l 空
l 有女生
l 有男生
用你偏好的程序设计语言编写下面过程(可以随意采用所希望的计数器和同步技术):
l woman_wants_to_enter
l man_wants_to_enter
l woman_leaves
l man_leaves
一开始总以为一定要用PV操作,写了一个管理信号量的PV操作类Semaphore,但是发现在这里实现不了想要的功能,因此没有用到Semaphore类
全部代码如下:
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Bath {
/**
* 表示澡堂的状态
* 0 无人在用
* 1 男人在用
* -1 女人再用
*/
private int bathState=0;
/**
* 澡堂当前男人的数量
*/
private int manCount=0;
/**
* 澡堂当前女人的数量
*/
private int womanCount=0;
public static void main(String[] args) {
Bath bath =new Bath();
ExecutorService exc =Executors.newCachedThreadPool(); //线程池
Random r=new Random();
//随机生成男或者女线程,偶数为女,奇数为男
while(true){
int human =r.nextInt(10);
if(human % 2==0)
exc.execute(bath.new Woman());
else
exc.execute(bath.new Man());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 代表男人的线程类
* @author chenmo
*
*/
class Man implements Runnable{
public void run() {
man_wants_enter();
go_to_sleep();
man_wants_leaves();
}
//男人进入澡堂
public synchronized void man_wants_enter(){
if(bathState==0){ //如果澡堂的状态是无人在用,则正常进入,并且把澡堂状态变为男人在用
manCount++;
bathState=1;
}else if(bathState==1){ //如果当前澡堂状态是男人在用,则直接进入
manCount++;
}else {
try {
//澡堂被女人占用,则当前线程等待
wait();
manCount++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(manCount+" man having a bath.");
}
public synchronized void man_wants_leaves(){
manCount--;
System.out.println(manCount+" man remain.");
//当澡堂的男人全部出来之后,唤醒等待的女人线程,并设置当前澡堂状态为无人在用
if(manCount==0){
bathState=0;
notify();
}
}
}
/**
* 代表女人的线程类
* @author chenmo
*
*/
class Woman implements Runnable{
public void run() {
woman_wants_enter();
go_to_sleep();
woman_wants_leaves();
}
public synchronized void woman_wants_enter(){
if(bathState==0){
//澡堂没人,正常进入
womanCount++;
bathState=-1;//澡堂状态变为女人在用
}else if(bathState==-1){ //澡堂已经有女人在用,直接进入
womanCount++;
}else{
try {
//澡堂被男人占用,当前线程等待
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
womanCount++;
}
System.out.println(womanCount+" woman having bath.");
}
public synchronized void woman_wants_leaves(){
womanCount--;
System.out.println(womanCount+" woman remain.");
if(womanCount==0) { //澡堂的女人全部出来之后,澡堂状态变为无人在用,并唤醒正在等待的男人线程
bathState=0;
notify();
}
}
}
//让线程随机睡眠一段时间,代表的是洗澡时间
public static void go_to_sleep(){
try{
Thread.sleep((long)(Math.random()*3000));
}catch(Exception e){
e.printStackTrace();
}
}
}
如果有童鞋可以用pv操作实现的,希望请教一下,谢谢。