如何定制BlockingQueue的阻塞行为

14
我想创建一个阻塞队列,基于自定义规则而不是队列中的项数来阻塞生产者。
例如:
生产者生成一些文件并放入队列中。消费者在进行一些分析后将它们传输到特定位置。
对于上述情况,如果队列中的总文件大小达到某个阈值,我希望生产者等待生成新文件。如果总大小未超过阈值,则队列可以接受任意数量的文件。

你现在找到任何解决方案了吗? - VB_
这是一个非常老的问题。我在任何实际应用程序中都没有使用过阻塞队列。因此,在那之后我并没有很努力地寻找解决方案。 - Amit Kumar Gupta
我有同样的需求,但我找不到现成的解决方案。我可能会直接复制粘贴Java中LinkedBlockingQueue(由Doug Lea编写)的代码,并修改现有的“容量”和“计数”检查逻辑,以实际调用自定义检查或其他内容。想不出更简单/更短的方法了。 - Evgeni
2个回答

4

我会建议你创建一个BlockingQueue的子类,例如像ArrayBlockingQueue一样,并添加一个简单的CountDownLatch。当计数值达到阈值时,CountDownLatch会启用各种take/remove方法。


我原本期望Java提供一些内置机制,通过覆盖某些方法或其他无法猜测的方式来自定义阻塞行为。因为规则可以根据需要进行更改。 - Amit Kumar Gupta
我能看出这样的类可能会很有用。但我不完全确定我理解你的要求。如果 take 应该阻塞直到队列中有10个元素,那么我是应该能够一次性 take 十个元素呢,还是应该等待9个元素再次变成10个? - aioobe
对于所提供的场景,take 操作不会等待队列为空。但是,如果文件的总大小(而不是文件数量)超过了阈值,put 操作将会等待。假设阈值为 5MB,则当队列中有 1000 个 5KB 的文件或者 100 个 50KB 的文件时(大致估算),put 操作将会等待。 - Amit Kumar Gupta
我建议使用组合而不是继承来修改阻塞队列的行为。 - Ivan
@Ivan,你是正确的。这可能更有意义。无论如何,您可能需要实现BlockingQueue的所有方法。 - aioobe

0

我认为你需要自己实现这个锁定机制。你可以使用wait/notify或者ReentrantLock/Condition,一个长变量来保存组合长度和一个LinkedList来保存文件。


这是我的解决方案队列中的最后一个选项,正如@aioobe所建议的。 :) - Amit Kumar Gupta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接