8

假设有 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 个 BlockingQueue。而当消费者从其队列中取出项目时,它使用BlockingQueue.take(),因此当队列中没有项目时它将被阻塞。当生产者将项目添加到任一队列时,它使用BlockingQueue.offer(). 这样它就永远不会被此操作阻塞,如果队列已满,它将变为“假”。此外,我们保留一个 AtomicInteger 来指示未满的队列数。每当生产者 P 想要将一个项目放入队列时,如果它返回 false,我们将 AtomicInteger 减 1。当它达到 0 时,生产者调用AtomicInteger.wait()。每当消费者从其队列中取出一个项目时,它也会检查 AtomicInteger。当它为 0 时,消费者将其增加 1 并调用AtomicInteger.notify()

请让我知道这个解决方案是否有意义。

非常感谢!

4

3 回答 3

1

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

于 2013-05-31T14:29:13.400 回答
0

您可以使用框架中的主题。

在activemq http://activemq.apache.org/how-does-a-queue-compare-to-a-topic.html

在 hornetq中 HornetQ 中 JMS 主题的确切示例

于 2013-05-31T14:23:24.497 回答
0

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

所以实际上停止生产者也不错。

如果您的队列已满,您应该尝试恢复平衡:您可以添加更多消费者。你可以提高消费者的表现。如果这是不可能的,那么确实应该限制生产者。这是一种避免内存不足错误设备上没有剩余空间的方法

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

更新

如果生产者不能在所有队列上发送,因为它的一个队列已满,则由他来缓冲,但缓冲是队列应该做的事情。

于 2013-05-31T14:42:20.760 回答