Java Producer-Consumer:生产者不会“通知()”消费者

时间:2015-10-14 19:03:36

标签: java

我正在尝试用一个生产者和一个消费者来实现生产者 - 消费者问题。生产者不能创造超过五种产品。如果没有,消费者不能消费产品。

我需要时将它们锁定在名为“monitor”的字段上。

这是我的代码:

import java.util.concurrent.TimeUnit;

public class ConsumerProducer {

private static final Object monitor = new Object();
private final int MAX_PRODUCTS = 5;
private String[] products = new String[MAX_PRODUCTS];

int slotToProduce = 0;
int slotToConsume = 0;

private Thread producer = new Thread(new Producer());
private Thread consumer = new Thread(new Consumer());

class Producer implements Runnable {

    private synchronized void produce() {
        synchronized (monitor) {
            // Acquiring access to produce a product
            while (slotToProduce - slotToConsume == MAX_PRODUCTS) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                }
            }

            // Producing a product
            System.out.println("Will now produce product " + slotToProduce);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
            }
            products[slotToProduce % MAX_PRODUCTS] = "Teddy Bear "
                    + Integer.toString(slotToProduce);
            System.out.println("Successfully produced product "
                    + products[slotToProduce % MAX_PRODUCTS]);
            slotToProduce++;

            // Notifying consumers if there were no products before
            if (slotToProduce - slotToConsume == 1) {
                notify();
            }
        }
    }

    @Override
    public void run() {
        while (true) {
            produce();
        }
    }

}

class Consumer implements Runnable {

    private synchronized void consume() {
        synchronized (monitor) {
            // Acquiring access to consume a product
            while (slotToProduce == slotToConsume) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                }
            }

            // Consuming a product
            System.out.println("Will now consume product "
                    + products[slotToConsume % MAX_PRODUCTS]);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
            }
            System.out.println("Successfully consumed product "
                    + products[slotToConsume % MAX_PRODUCTS]);
            slotToConsume++;

            // Notifying producers if before there were no spaces to produce
            // a product
            if (slotToProduce - slotToConsume == MAX_PRODUCTS - 1) {
                notify();
            }
        }
    }

    @Override
    public void run() {
        while (true) {
            consume();
        }
    }
}

public static void main(String args[]) {
    final ConsumerProducer cp = new ConsumerProducer();
    cp.producer.start();
    cp.consumer.start();
}

}

但是,当我运行程序时,输出为:

  • 现在将生产产品0
  • 成功生产产品Teddy Bear 0
  • 现在将生产产品1
  • 成功生产产品Teddy Bear 1
  • 现在将生产产品2
  • 成功生产产品Teddy Bear 2
  • 现在将生产产品3
  • 成功生产产品泰迪熊3
  • 现在将生产产品4
  • 成功生产产品Teddy Bear 4

从这里程序暂停。

所以问题是:即使我在同一个对象“监视器”上同步消费者和生产者,为什么消费者始终处于睡眠状态?

1 个答案:

答案 0 :(得分:3)

您正在监视对象上进行同步。但是你调用sleep并通知生产者和消费者对象。

所需的更改:

  1. 在监视器上调用wait(),notify()
  2. 删除同步方法。只保留监视器对象的同步。
  3. 永远不要忽略中断的异常!
  4. 考虑使用队列。查看接口java.util.concurrent.BlockingQueue