我正在尝试用 Java 解决以下问题:
There is a bar in which smoking and non-smoking customers go. The bar has a limited number of seats for customers. Smoking and non-smoking customers can't be present in the bar at the same time. Every customer spends some time traveling to the bar, then enters and spends some time in the bar and finally leaves, freeing his seat for other customers waiting to get in. After the smoking customers have left the bar, the air inside needs to be refreshed so that non-smoking customers can come.
Create a simple simulation of this problem using threads synchronization methods in Java and make sure deadlock doesn't occur.
我能想到的是以下代码。不过我有一个问题 - 如何实现酒吧需要锁定一段时间以刷新空气的条件?
这是代码:
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();
}
}
}
如何锁定空气清新的酒吧?
最佳答案
我创建了 Magee & Kramer 关于桥上红色和蓝色汽车示例的修改版本。请参阅此处(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();
}
}
关于java - 无法解决与Java Threads相关的教科书示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13653576/