【发布时间】:2011-01-06 16:47:31
【问题描述】:
我目前有一个使用BlockingQueue 作为数据存储的并发队列实现。我现在需要引入第二种具有更高优先级的对象,将我引向原始队列的饥饿/优先级队列。因此,我们正在处理由多个线程生成的 A 类型和 B 类型的对象。任何类型 B 的对象都应该在类型 A 的对象之前处理,但除了必须保持 FIFO 顺序之外。因此,如果插入 { 1A, 1B, 2A, 3A, 2B },则顺序应为 {1B, 2B, 1A, 2A, 3A}
我尝试了单个PriorityBlockingQueue 将类型 B 推到前面,但我无法保持 FIFO 要求(相同类型的项目之间没有自然顺序)。
我的下一个想法是使用两个并发队列。在协调两个队列之间的访问时,我正在寻找常见的问题或注意事项。理想情况下,我想做这样的事情:
public void add(A a)
{
aQueue.add(a);
}
public void add(B b)
{
bQueue.add(b);
}
private void consume()
{
if(!bQueue.isEmpty())
process(bQueue.poll());
else if(!aQueue.isEmpty())
process(aQueue.poll());
}
如果两个队列都是ConcurrentLinkedQueue(或在此处插入更合适的结构),我是否需要任何同步或锁定?注意我有很多生产者,但只有一个消费者(单线程ThreadPoolExecutor)。
编辑:如果 B 在 isEmpty() 检查后进入,则可以处理 A 并在下一次 consume() 调用时处理它。
【问题讨论】:
-
在处理 A 对象之前处理 B 对象有多重要?在您当前的代码中,如果在调用 isEmpty() 之后插入了 B 对象,您会错过它。有两个不同的答案,取决于你必须做什么......
-
@Jonathan 不重要。我打算添加它并以某种方式将其排除在外。问题已更新。
标签: java concurrency queue