我正在尝试用Java解决以下问题:
有吸烟和非吸烟顾客去的酒吧。酒吧 为客户提供的座位数量有限。吸烟和不吸烟 客户不能同时出现在酒吧。每个客户 花一些时间去酒吧,然后进入并花费一些 在酒吧的时间,最后离开,释放他的座位为其他 客户等待进入。吸烟客户离开后 酒吧,里面的空气需要刷新,以便禁止吸烟 客户可以来。
使用Java中的线程同步方法创建此问题的简单模拟,并确保不会发生死锁。
我能想到的是以下代码。我有一个问题 - 如何实现条形需要在刷新空气所需时间内锁定的条件?
这是代码:
class Bar {
int maxP;
int curP;
String state;
public Bar(int maxP) {
this.maxP = maxP;
curP = 0;
state = "none";
}
public synchronized void enterBar(Customer customer) {
if(state == "none") {
state = customer.smokingStatus;
}
while((curP == maxP) || state != customer.smokingStatus) {
System.out.println(customer.name+" " + customer.smokingStatus + " is waiting to enter the bar. ");
try {
wait();
if(curP == 0 && state == "none") {
state = customer.smokingStatus;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
curP++;
System.out.println(customer.name +" "+ customer.smokingStatus + " enters the bar and relaxes. ");
}
public synchronized void leaveBar(Customer customer) {
curP--;
if(curP == 0) {
state = "none";
}
System.out.println(customer.name +" " + customer.smokingStatus + " stops relaxing and leaves the bar.");
notifyAll();
}
}
然后上课客户:
class Customer extends Thread {
String name;
String smokingStatus;
Bar bar;
public Customer(String name, String smoker, Bar bar) {
this.name = name;
this.smokingStatus = smoker;
this.bar = bar;
}
public void run() {
System.out.println(this.name + " is traveling to the bar.");
try {
sleep((int)(Math.random()*1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
bar.enterBar(this);
try {
sleep((int)(Math.random()*5000));
} catch (InterruptedException e) {
e.printStackTrace();
}
if (this.smokingStatus.equals("smoker")){
System.out.println("After I've been here the bar's air needs some refreshing.");
try {
sleep((int)(Math.random()*2000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
bar.leaveBar(this);
}
}
最后是main()方法:
class MainApp {
public static void main(String args[]) {
Bar s = new Bar(5);
for(int i = 0; i < 10; i++) {
String smokingStatus;
smokingStatus = Math.random() > 0.5 ? "smoker" : "nonsmoker";
(new Customer("Customer " + i, smokingStatus, s)).start();
}
}
}
如何锁定空气清新条?
答案 0 :(得分:2)
我已经创建了Magee&amp; amp;的修改版本。克莱默关于红色&amp; amp;在桥上的蓝色车。见这里(http://flylib.com/books/en/2.752.1.48/1/)。我添加了TIME_TO_CLEAR_AIR和MAX_PATRONS内容。应该非常接近你想要的。重命名变量以适应。根据客户类型调用适当的进入/退出方法。
public class SafeBar {
// smokers in the bar
private int smokers = 0;
private int MAX_PATRONS = 20;
// non-smokers in the bar
private int nonSmokers = 0;
// last time a smoker left the bar
private long lastSmoke = 0;
private long TIME_TO_CLEAR_AIR = 10000; // 10 seconds
synchronized void smokerEnter() throws InterruptedException {
while (nonSmokers>0||smokers==MAX_PATRONS) {
wait();
}
++smokers;
}
synchronized void smokerExit(){
--smokers;
if (smokers==0) lastSmoke = new Date().getTime();
notifyAll();
}
synchronized void nonSmokerEnter() throws InterruptedException {
long checkTime = 0;
while (smokers>0||nonSmokers==MAX_PATRONS||(checkTime = new Date().getTime()) - lastSmoke < TIME_TO_CLEAR_AIR) {
if (checkTime - lastSmoke < TIME_TO_CLEAR_AIR)
wait(TIME_TO_CLEAR_AIR - (checkTime - lastSmoke));
else
wait();
}
++nonSmokers;
}
synchronized void nonSmokerExit(){
--nonSmokers;
notifyAll();
}
}
答案 1 :(得分:1)
在leaveBar(Customer)
方法中,如果离开酒吧的顾客是吸烟者并且是最后一个,那么开始一个睡眠一段时间(刷新时间)的新线程,最后告诉酒吧空气清新。空气清新后,请致电notifyAll()
让下一位顾客进入吧台。