Javaでモニタを使用して単一のコンシューマ/プロデューサの問題を解決しようとしています。コードは次のとおりです。私はこのコードを実行すると、それはついに詰まるでしょう。最も一般的なケースは、コンシューマがwait()
を呼び出し、プロデューサはコンシューマを生成し続けますが、コンシューマに通知することはできません(notify()
を呼び出します)。私はなぜそれが起こっているのか分からない。 Javaコード:私のJavaプログラムのモニタがデッドロックになる
import java.util.*;
class Monitor {
int length;
int size;
int begin, end;
int queue[];
private static Random randGenerator;
public Monitor() {}
public Monitor(int length) {
this.length = length;
this.size = 0;
begin = end = 0;
queue = new int[length];
randGenerator = new Random(10);
}
public synchronized void produce() throws InterruptedException {
while(size == length) {
System.out.println("Producer waiting");
wait();
}
int produced = randGenerator.nextInt();
size++;
queue[end] = produced;
end = (end + 1) % length;
System.out.println("Produce element " + produced + " size "+size);
// When size is not 1, no thread is blocked and therefore don't need to notify
if(size == 1) {
System.out.println("Notify consumer");
notify();
}
}
public synchronized void consume() throws InterruptedException {
while(size == 0) {
System.out.println("Consumer waiting, size " + size);
wait();
}
size--;
System.out.println("Consume element " + queue[begin] + " size " + size);
begin = (begin + 1) % length;
if(size == length - 1) {
System.out.println("Notify producer");
notify();
}
}
}
class Producer implements Runnable {
Monitor producer;
public Producer(Monitor m) {
producer = m;
}
@Override
public void run() {
producer = new Monitor();
System.out.println("Producer created");
try {
while(true) {
producer.produce();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
Monitor consumer;
public Consumer(Monitor m) {
consumer = m;
}
@Override
public void run() {
System.out.println("Consumer created");
consumer = new Monitor();
try {
while(true) {
consumer.consume();
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class monitorTest {
public static void main(String args[]) {
Monitor monitor = new Monitor(10);
Thread t1 = new Thread(new Producer(monitor));
Thread t2 = new Thread(new Consumer(monitor));
t1.start();
t2.start();
}
}
2人の消費者が最初に来て、両方とも 'wait()'と入力したとします。プロデューサが来たら、1つの 'notify()'を発行します。その後直ちに、消費者が目覚める前に、別のプロデューサが来て、アイテムを追加するが通知は一切出さない。今、消費者は1人しか目覚めされません。 – ZhongYu
@ ZhongYuご意見ありがとうございます。主な機能でプロデューサと消費者を1つだけ作成しても、プログラムは正常に実行できません。何故ですか?私はプログラムが単一の生産者/消費者の問題を対象としていると述べました。 –
もう一度 'new Monitor()'を呼び出すべきではありません。main()で作成されたモニタを使用してください。 – ZhongYu