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

标签 java concurrency producer-consumer

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

希望这有帮助!

关于java - 我的 java 程序中的监视器陷入死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42241094/

相关文章:

java - 修改现有的 GWT 应用程序

concurrency - JDK8中的ConcurrentHashmap代码解释

php - 当用户访问主题时放置标记 : trouble

c - C中的生产者/消费者,带有pthread信号量和多线程

python - 在 Linux 上使用 Python 3.x 的多处理生产者消费者

java - 多态歧义区分是如何工作的?

java - LuaJ - 在 Java 中创建 Lua 函数

java - 如何从文件中读取 'integer'类型的数据?

loops - 是否可以从外部功能停止股票行情/股票报价?

c++ - 快速 C++ 单生产者单消费者实现