我的 java 程序中的监视器陷入死锁

Monitor in my java program gets into a deadlock

我试图在Java中使用监视器解决单个consumer/producer问题,代码如下。当我运行这段代码的时候,它终于卡住了。最典型的情况就是消费者调用了wait(),然后生产者一直在生产但是不能通知消费者(虽然会调用notify())。我不知道为什么会这样。 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();
    }
}

当每个线程的控制进入produce()consume()方法时,大小和长度都为零,因此两个线程都在等待另一个线程通知。打破这个,你的代码就会摆脱僵局。

public synchronized void produce() throws InterruptedException {
    while(size == length) { // size is 0 and length is 0; so wait
        System.out.println("Producer waiting");
        wait();
    }

public synchronized void consume() throws InterruptedException {
    while(size == 0) { // size is 0 so wait
        System.out.println("Consumer waiting, size " + size);
        wait();
    }

发生这种情况是因为您有一个默认构造函数,您在 Producer 和 Consumer 对象的 run() 方法中调用它。

class Producer implements Runnable {
    Monitor producer;
    public Producer(Monitor m) {
        producer = m;
    }
    @Override
    public void run() {
        producer = new Monitor(); // REMOVE THIS

class Consumer implements Runnable {
    Monitor consumer;
    public Consumer(Monitor m) {
        consumer = m;
    }
    @Override
    public void run() {
        System.out.println("Consumer created");
        consumer = new Monitor(); // AND REMOVE THIS

希望对您有所帮助!