首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java生产者-消费者:生产者不通知消费者

Java生产者-消费者:生产者不通知消费者
EN

Stack Overflow用户
提问于 2015-10-14 19:03:35
回答 1查看 86关注 0票数 0

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

当需要的时候,我把他们都锁在一个叫做“监视器”的领域里。

这是我的代码:

代码语言:javascript
复制
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产品
  • 成功生产泰迪熊0
  • 将生产产品1
  • 成功生产泰迪熊1号
  • 将生产产品2
  • 成功生产泰迪熊2
  • 将生产产品3
  • 成功生产泰迪熊3
  • 将生产产品4
  • 成功生产泰迪熊4

从现在起节目停止了。

所以问题是:即使我在同一个对象“监视器”上同步了消费者和生产者,为什么消费者总是在睡觉呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-14 19:12:26

你在监视对象上同步。但是,您可以在生产者和使用者对象上调用睡眠和通知。

所需更改:

  1. 调用wait(),在监视器上通知()
  2. 去除方法上的同步。仅在监视器对象上保持同步。
  3. 永远不要忽视被打断的异常!
  4. 考虑使用队列。查看接口java.util.concurrent.BlockingQueue
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33133551

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档