生产者消费者有一个生产者和多个消费者

时间:2016-08-02 11:29:12

标签: java multithreading producer-consumer

我正在实现生产者 - 消费者,其中要消费的物品是1000种类型-0,类型-1,...,类型-999。

生产者在队列中插入type-i项。消费者使用它来更新类型为i的状态机(每个类型i一个状态机)基于从队列中删除的项(类型-i)。有多个消费者从同一队列(和一个生产者)读取

条件是如果某个消费者正在处理类型-i的项目,那么其他消费者不能处理相同类型的项目,所以如果其他消费者拿起相同类型的下一个类型-i,所有消费者都被阻止,这是不好的溶液

另一个解决方案是每个类型的1000个队列和1000个消费者,这是不可行的

另一种解决方案是拥有10个队列和10个消费者(每个队列一个)并为Q-1分配100种类型,向Q2等分配100种类型。但问题是如果消费者-J需要大量时间来处理项目-i队列中的所有其他项目将面临延迟,但其他消费者-k可能闲置。

我们可以在这里使用什么好的设计模式?

更新

  1. 解决方案-1:每个类型(1个队列 - 1个消费者):最佳解决方案,但很多线程
  2. 解决方案-2:(1个队列 - 消费者)每n类型:问题是我们可能达到所有消费者都在等待处理类型的状态-i作为第一个消费者仍然在处理类型-i项目持有锁定(类型-i) )
  3. 更新2:

    此处物品的订购是IMP,不能更改。您可以假设每个类型的一个状态机-i和消费者根据收到的新项目(类型-i)修改状态。现在,您可以看到为什么项目排序很重要

2 个答案:

答案 0 :(得分:1)

如果我们深入研究问题,我们可以看到每个项目类型都以并行方式处理:没有资源争用,没有进程之间的合作,除了所有这些项目都保存在同一个缓冲区中的事实。所以这听起来不是最好的设计选择。

如果您在处理项目时需要FIFO顺序,则可以将它们放入队列中,而在另一个“侧面”,一个所谓的“调度程序”线程“将它们从队列中取出。然后,每个单个线程* item类型带有它自己的队列,从调度程序线程加载。所以你有1000 + 1生产者/消费者问题

*是的,1000个线程不是很少....所以你可以决定启动1000 / k线程,其中一个线程处理一个范围ok k类型

如果需要负载平衡,可以为每个线程使用不同的范围,计算其队列平均大小。更复杂,也许太多了

答案 1 :(得分:0)

在此处了解Apache Storm的基本原理中的“队列和工作者范例”的限制 - queues & workers paradigm - storm rationale。您的要求主要用于可扩展的实时处理,可以使用Apache Storm或Apache Spark解决。阅读更多here