Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java程序中的监视器陷入死锁_Java_Concurrency_Producer Consumer - Fatal编程技术网

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

java程序中的监视器陷入死锁,java,concurrency,producer-consumer,Java,Concurrency,Producer Consumer,我试图用Java中的monitor解决单个消费者/生产者的问题,代码如下。当我运行这段代码时,它最终会被卡住。最典型的情况是消费者调用wait(),然后生产者继续生产,但无法通知消费者(尽管它将调用notify())。我不知道为什么会这样。Java代码: import java.util.*; class Monitor { int length; int size; int begin, end; int queue[]; private static

我试图用Java中的monitor解决单个消费者/生产者的问题,代码如下。当我运行这段代码时,它最终会被卡住。最典型的情况是消费者调用
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();
    }
}

当每个线程的控件进入
product()
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();
    }


之所以会发生这种情况,是因为您在生产者和消费者对象的
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


希望这有帮助

假设有两个消费者先来,两个都输入
wait()
。然后一个制作人来了,发布一个
notify()
。紧接着,在任何消费者被叫醒之前,另一个制作人来了,添加了一个项目,但没有任何通知。现在,只有一个消费者会被叫醒。@ZhongYu感谢您的评论。我在主函数中只创建了一个生产者和一个消费者,程序仍然无法正常运行。为什么呢?请注意,我已经提到该程序是针对单个生产者/消费者问题的。您不应该再次调用
new Monitor()
-删除这两行后,只需使用main()@ZhongYu中创建的监视器即可,它工作正常。谢谢(这对我来说是个多么愚蠢的错误啊哈哈)。由于您没有发布答案(确实不需要…),我会将anacron的答案标记为已接受。但我会将monitor.length初始化为10(
monitor monitor=new monitor(10)
),因此长度不应为0,而应为10。我错了吗?我在
语句开头之前打印了大小和长度。我得到了尺寸=0,长度=0。
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