制片人消费者 - 锁定什么

时间:2016-11-20 16:42:44

标签: java multithreading producer-consumer

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

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

只有一个队列,我写它来保存通用对象MyQueue。因此,许多生产者和消费者共享这个队列。说X和Y的对象放在单个队列上。如果X在其上,则ConsumerOfX被唤醒并移除X.与Y相同。

我不知道队列是否最好通知消费者'我现在有一个X对象',或者生产者更好地说'嘿,X的消费者,我刚刚把X放入队列'。我猜测队列的生产者不应该知道队列的消费者。

有更简洁的方法吗?

1 个答案:

答案 0 :(得分:0)

这取决于实施。如果存在针对不同产品的单独队列,则必须使用单独的锁对象来保护每个队列(该锁对象可以是队列本身)。

此外,如果您正在编写队列的实现,那么您可能决定将Lock对象作为私有变量。另外,您可以检查队列是否已满,您可以选择在私有锁变量上使用wait。使用任何对象后,您可以在私有锁定对象上调用notifyall(或notify,但最好notifyall)。类似的方式,如果消费者调用方法在队列为空时从队列中获取元素,则可以使用waitnotify逻辑。这样,您的队列类将负责使用私有变量对象进行锁定和通知。由于队列具有私有变量lovk对象,因此每个队列实例都有自己独立的Lock对象。

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

<强>更新

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

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

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

如果您的实现是希望队列不要处理同步,那么在调用Producrer和{{{{}}之前,您应该有一个Consumerenqueue可以同步的共享对象1 {} dequeue。此共享对象可以是queue本身的实例。需要在共享对象的synchronized块内调用queuewait