首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >生产者消费者-锁定什么

生产者消费者-锁定什么
EN

Stack Overflow用户
提问于 2016-11-21 00:42:44
回答 1查看 418关注 0票数 0

我有许多生产者/消费者的不同类型的对象,例如ProducerOfX,ProducerOfY,ConsumerOfX,ConsumerOfY。生产者将一个对象(X或Y)放到一个队列上,并通知它的相关消费者(ProducerOfX只通知ConsumerOfX )。

为了让它起作用,我需要一个对象作为锁。我的问题是,我是否要创建一个对象,例如new X(),并让ProducerOfX和ConsumerOfX对此调用wait/notify?

将只有一个队列,我已经编写了它来保存泛型对象MyQueue。因此,许多生产者和消费者共享这个队列。例如X和Y的对象被放在单个队列中。如果X在它上面,ConsumerOfX会被唤醒并删除X。与Y相同。

我想知道是让队列通知消费者‘我现在有一个X对象’还是让生产者说‘嘿,X的消费者,我刚刚在队列中放了一个X’更好。我猜队列的生产者不应该知道队列的消费者。

有没有更干净的方法来做这件事?

EN

回答 1

Stack Overflow用户

发布于 2016-11-21 02:23:08

这取决于实现方式。如果不同的产品有不同的队列,那么每个队列必须用一个单独的锁对象(这个锁对象可能是队列本身)来保护。

此外,这取决于您是否正在为队列编写实现,然后您可以决定将Lock对象作为私有变量。此外,您可以检查队列是否已满,还可以选择在私有锁变量上设置wait。一旦使用了任何对象,就可以在私有锁对象上调用notifyall (或notify,尽管notifyall更可取)。类似地,如果使用者在队列为空时调用该方法从队列中获取元素,则可以使用waitnotify逻辑。这样,您的queue类将负责使用私有变量对象进行锁定和通知。由于queue有私有变量lovk对象,因此每个queue实例都有自己单独的Lock对象。

另一种方式是,如果队列是普通队列,可能不是你在写队列,那么你需要保护调用添加和获取方法的代码。以防您对不同的产品(x、y等)有单独的队列然后您需要为每个队列使用不同的Lock对象。这是防止死锁所必需的,可能会发生这样的情况(如果我们没有sepatrate锁对象),一个consumerX正在等待queueX插入一个元素(因为它是空的),而另一个producerY没有机会插入到queueY中(因为它是满的)。因此,您需要单独的锁对象。

更新

@TheCoder如果你只有一个生产者和消费者都在同一类型的产品中,那么一个队列就可以了。现在出现了共享对象的问题,两者都应该在共享对象上进行通信。这取决于实现,如果你希望Queue来处理它,那么Queue可以有一个私有字段private Object monitor = new Object();,并且可以让enqueuedequeue方法在“`monitor”上同步。

dequeue方法中,如果queue为空,则在while循环中调用monitor.wait(),直到队列为空。如果队列不为空,则从队列中移除对象并调用monitor.notifyAll();

enqueue方法中,如果队列已满,则调用while循环中的monitor.wait(),直到队列已满。如果队列未满,则在队列中添加一个对象并调用monitor.notifyAll();

如果您的实现不希望queue负责同步,那么在调用Consumer上的enqueuedequeue之前,您应该有一个共享对象,ProducrerConsumer可以在该对象上进行同步。这个共享对象可以是queue本身的实例。需要在共享对象的synchronized块中调用waitnotifyAll

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40706614

复制
相关文章

相似问题

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