生产者/消费者 - 生产者将数据添加到集合中而不会阻塞,消费者会批量使用集合中的数据

时间:2014-03-05 22:51:39

标签: java collections concurrency queue producer-consumer

我有一个生产者/消费者用例,这有点不寻常。 我有一些真实世界的用例,我希望他们能够在没有阻塞的情况下将对象添加到集合中。 消费者(只有一个)应该阻止,直到集合中有一定数量的对象可用(例如500),然后大量消费它们。虽然少于500,但它应该阻止并等待集合填充。我不介意队列是否超过这个值(700,1000等)很短的时间。

我目前似乎找不到解决此问题的解决方案。 我正在考虑使用ConcurrentLinkedQueue并让消费者定期检查队列是否有足够的数据,但这似乎适得其反。

另一个想法是使用LinkedBlockingQueue。生产者不会阻止(除非队列已满,这意味着它有Integer.MAX_VALUE值 - 这不是我的情况,所以一切都很好)。使用者将执行queue.take()并将元素添加到内部集合中。当内部集合达到500个元素时,它将批量使用它们。

你有任何提示吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

最后我选择了LinkedBlockingQueue。

制作人将项目添加到队列中。

使用者将执行queue.poll()并将项目保存到内部集合中。当内部集合达到500个元素时,它将批量使用它们。我也可以设置一些超时。例如,如果X秒已经过去,我将使用该集合,即使它的项目少于所需的项目(例如220)。

答案 1 :(得分:1)

您可以简单地引入一个中间队列和使用者/生产者,它将从生产者填充队列中的项目,将它们存储在列表中,一旦列表大小为500,将列表本身放入队列中读取由消费者。消费者将阻止,直到下一个500项的列表可用。

当然,您也可以将此逻辑封装在生产者共享的对象中:生产者将其项目添加到“Batcher”对象中。 batcher对象将项添加到私有列表,一旦列表大小为500,batcher就会将列表添加到队列中。只需确保batcher的addItem()方法已同步。这样可以避免额外的线程和队列。