1

我有以下阻塞队列;

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

在哪里

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

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

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

如果不是 BlockingQueue 的替代品是什么?

4

3 回答 3

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。

于 2012-03-19T17:40:12.333 回答
3

这当然是可能的,假设您对到达队列前面的与您的条件不匹配的元素会发生什么反应很灵活。

一种简单的方法是

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

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

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

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

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

然后设置您的消费者以使用正确的作者队列。

于 2012-03-19T17:35:21.083 回答
0

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

于 2012-03-19T17:34:32.223 回答