我試圖解決使用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()'。然後生產者來了,發出一個'notify()'。緊接着,在任何消費者被喚醒之前,另一個生產者來了,添加了一個項目,但沒有任何通知。現在,只有一個消費者會被喚醒。 – ZhongYu
@中裕感謝您的評論。我在主函數中只創建一個生產者和一個消費者,程序仍然無法正常運行。這是爲什麼?請注意,我已經提到該計劃針對單一生產者/消費者問題。 –
你不應該再次調用'new Monitor()' - 只需使用在main()中創建的監視器() – ZhongYu