Ich versuche, einzelne Verbraucher/Produzent Problem mit Monitor in Java zu lösen, und der Code ist wie folgt. Wenn ich diesen Code ausführe, wird er endlich stecken bleiben. Der typischste Fall ist, dass der Verbraucher wait()
anruft und der Produzent dann weiter produziert, aber den Verbraucher nicht benachrichtigen kann (obwohl er notify()
anrufen wird). Ich weiß nicht, warum es passiert. Java-Code:Monitor in meinem Java-Programm in einen Deadlock
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();
}
}
Angenommen, zwei Verbraucher kommen zuerst, beide geben 'wait()' ein. Dann kommt ein Producer, der einen 'notify()' ausgibt. Unmittelbar danach, bevor ein Verbraucher geweckt wird, kommt ein anderer Produzent, fügt einen Artikel hinzu, aber ohne Benachrichtigungen. Jetzt wird nur ein Verbraucher geweckt. – ZhongYu
@ZhongYu Danke für Ihren Kommentar. Ich erstelle nur einen Produzenten und einen Verbraucher in der Hauptfunktion, und das Programm kann noch nicht normal laufen. Warum das? Beachten Sie, dass ich erwähnt habe, dass das Programm auf ein Problem mit einzelnen Produzenten/Verbrauchern abzielt. –
Sie sollten 'new Monitor()' nicht erneut aufgerufen haben - verwenden Sie einfach den in main() erstellten Monitor – ZhongYu