如何实现具有多个使用者和多个队列的消费者 - 生产者

时间:2013-05-31 14:13:04

标签: java concurrency messaging producer-consumer java.util.concurrent

假设有1个生产者P和2个消费者C1和C2。并且有2个队列Q1和Q2,都具有特定容量。

P将产生物品并交替进入Q1和Q2。物品是为特定消费者生产的,不能被其他消费者消费。我如何在Java中实现以下内容:在我启动3个线程后,如果Q1为空,则线程C1被阻塞,直到在Q1中存在某些内容时通知它。 Q2也是如此。当Q1和Q2都满时,P将被阻塞,直到Q1或Q2未满时通知它。

我正在考虑使用BlockingQueue,它会在队列为空时阻止使用者。但问题是当其中一个队列已满时,生产者将被阻止。我们可以用Java来解决这个问题吗?

更新

我自己有一个解决方案,但我不确定它是否有效。我们仍然可以有2个BlockingQueues。当消费者从其队列中获取项目时,它使用BlockingQueue.take(),因此当队列中没有项目时它将被阻止。当生产者将项目添加到任一队列时,它使用BlockingQueue.offer()。因此,它永远不会被此操作阻止,并且如果队列已满,它将变为“false”。另外,我们保留一个AtomicInteger来指示未满的队列数。每当生产者P想要将一个项目放入队列时,如果它得到错误的返回,我们将AtomicInteger减少1.当它达到0时,生产者调用AtomicInteger.wait()。每当消费者从其队列中获取项目时,它也会检查AtomicInteger。当它为0时,消费者将其增加1并调用AtomicInteger.notify()

请告诉我这个解决方案是否有意义。

非常感谢!

3 个答案:

答案 0 :(得分:1)

您是否考虑过Striped Executor Service。这将使您能够解决问题将您的消费者放入一个更有效的池中。

答案 1 :(得分:0)

答案 2 :(得分:0)

无论您选择哪种数据结构/信息服务器,都可以使用其中任何一种资源。内存或磁盘空间总是有限制。

所以实际上制作人停止了也不错。

如果你的队列正在填满,你应该尝试恢复余额:你可以添加更多的消费者。您可以改善消费者的表现。如果这是不可能的,那么应该真正扼杀生产者。这是一种避免内存不足错误的方法设备上没有剩余空间

最后,无论如何,数据中心都有责任监控队列。如果您的队列的填充程度达到限制,他们应通知您,例如> 80%。

更新

如果生产者无法发送所有队列,因为其中一个队列已满,则由他来缓冲,但缓存是队列应该做的事情。