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

Java 如何实现具有多个消费者和多个队列的消费者生产者,java,concurrency,messaging,producer-consumer,java.util.concurrent,Java,Concurrency,Messaging,Producer Consumer,Java.util.concurrent,假设有1个生产者p和2个消费者C1和C2。有两个队列Q1和Q2,它们都具有特定的容量 p将生成项目,并将其交替放入Q1和Q2。商品是为特定消费者生产的,其他消费者不能消费。如何在Java中实现以下内容:启动3个线程后,如果Q1为空,线程C1将被阻塞,直到收到Q1中有内容的通知为止。第二季度也是如此。当Q1和Q2都已满时,P将被阻止,直到当Q1或Q2未满时收到通知 我想使用BlockingQueue,当消费者的队列为空时,它将阻止消费者。但问题是,当其中一个队列已满时,生产商将被阻塞。Java中是

假设有1个生产者p和2个消费者C1和C2。有两个队列Q1和Q2,它们都具有特定的容量

p将生成项目,并将其交替放入Q1和Q2。商品是为特定消费者生产的,其他消费者不能消费。如何在Java中实现以下内容:启动3个线程后,如果Q1为空,线程C1将被阻塞,直到收到Q1中有内容的通知为止。第二季度也是如此。当Q1和Q2都已满时,P将被阻止,直到当Q1或Q2未满时收到通知

我想使用BlockingQueue,当消费者的队列为空时,它将阻止消费者。但问题是,当其中一个队列已满时,生产商将被阻塞。Java中是否有任何数据结构可用于解决此问题

更新

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

请让我知道这个解决方案是否合理


非常感谢

您可以使用框架中的主题

在activemq中


在《大黄蜂》中,你是否考虑过一个新角色。这将允许您解决您的问题,并将您的消费者放入一个更加高效的池中。

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

所以事实上,制片人被停职并不坏

如果您的队列已满,您应该尝试恢复平衡:您可以添加更多消费者。您可以提高消费者的绩效。如果这是不可能的,一些事情应该真正扼杀生产者。这是一种避免内存不足错误或设备上没有剩余空间的方法

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

更新


如果制作人无法发送所有队列,因为其中一个队列已满,则应由制作人进行缓冲,但缓冲是队列应该做的事情。

p将在Q1和Q2都已满时被阻止。
在什么、Q1、Q2或其他同步器上被阻止?您可能不需要两个队列。使用单个阻塞队列,从制作人处呼叫
提供(E E,长超时,时间单位)
,从消费者处呼叫
获取
,然后您就不必担心队列大小不均了。谢了。我修改了这个问题,“商品是为特定消费者生产的,不能被其他消费者消费。”所以我不知道在这种情况下我们是否可以使用单个BlockingQueue。这其实是我遇到的一个真正的问题。嗨,约翰·温特,谢谢。如果队列未满,则应阻止P。阻塞什么并不重要。在这种情况下,使用单独的队列是有意义的。使用生产者提供的
offer(E E,long timeout,TimeUnit)
和消费者提供的
take
,这样三个线程将阻塞,直到空间/项目可用为止。如果您希望在队列2已满时仍然能够为队列1生成项目,或者反之亦然,那么您可能需要两个生产者而不是一个生产者。谢谢。有没有办法只使用java并发而不使用其他库?这不是另一个库,它是一个使用标准Executor服务功能的类。谢谢。有没有一种方法可以在不使用其他库的情况下只使用java并发性?如果您想要实现生产者/消费者(standart JMS)的设计模式,您必须使用第三方库