BlockingQueue - 仅获取特定对象。

时间:2012-03-19 17:30:04

标签: java concurrency blockingqueue

我有以下blockingQueue;

  final BlockingQueue<Message> blockingQueue = new LinkedBlockingQueue<Message>();

其中

public class Message {
    private String author;
    private String text;
        .......
//setters and getters
.....
}

我有一个将消息放入队列的生产者。

现在我的目标是创建消费者,这些消费者能够从特定作者的特定队列消息中获取特定消息吗?可能吗?

如果没有什么可以替代BlockingQueue?

3 个答案:

答案 0 :(得分:4)

您可以使用字符串为ConcurrentMap<String,BlockingQueue<Message>>

author
ConcurrentMap<String,BlockingQueue<Message>> map = ...;
public Message consume(String str){
  return map.get(str).take();
}
public void produce(Message message){
  map.get(message.getAuthor()).put(message);
}

这需要为每位作者提供一个独特的BlockingQueue。

答案 1 :(得分:3)

这当然是可能的,假设你对那些符合你的标准的队列前面的元素会发生什么变化是灵活的。

一种简单的方法就像是

while (true) {
   Message message = blockingQueue.take();
   if ( !message.author.equals(expectedAuthor) ) {
      continue;
   }
}

现在,如果您想知道是否可以从队列中 cherry-pick 元素,而将其他元素保留在原位,那么使用queue数据类型是不可能的。您可以使用某种Deque(双端队列),将您不关心的元素放在临时堆栈中,然后在找到所需的元素时重新插入它们。但是你最好只使用一个只包含你关心的元素的单独队列。

例如,您可以拥有一个消耗队列中每条消息的线程,然后将其重新分配到更具体的队列:

Map<String, BlockingQueue<Message>> authorQueues;
BlockingQueue<Message> allMessages;

while(true) {
    Message nextMessage = allMessages.take();
    authorQueues.get(nextMessage.getAuthor()).put(nextMessage);
}

然后将您的使用者设置为使用正确的作者队列。

答案 2 :(得分:0)

您可以尝试使用PriorityBlockingQueue或为每种消息类型保留单独的队列,但是您必须通过某个更高的对象进行同步(否则多个线程可以同时获取多个消息)。