Javaで次の問題を解決しようとしています:
喫煙者と禁煙者が通うバーがあります。バーには限られた数の顧客用の席があります。喫煙者と禁煙者が同時にバーにいることはできません。すべての顧客はバーに移動するのに時間を費やし、バーに入ってしばらく過ごし、最後に立ち去り、他の顧客が入るのを待っています。喫煙している顧客がバーを離れた後、内部の空気をリフレッシュする必要があります禁煙のお客様が来られるように。
Java のスレッド同期メソッドを使用してこの問題の簡単なシミュレーションを作成し、デッドロックが発生しないことを確認してください。
私が思いついたのは、次のコードでした。ただし、問題が 1 つあります。空気をリフレッシュするために必要な時間、バーをロックする必要があるという条件を実装するにはどうすればよいですか?
これはコードです:
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();
}
}
}
空気をリフレッシュするためにバーをロックするにはどうすればよいですか?