首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BlockingQueue -仅获取特定对象。

BlockingQueue -仅获取特定对象。
EN

Stack Overflow用户
提问于 2012-03-20 01:30:04
回答 3查看 2.3K关注 0票数 1

我有以下blockingQueue;

代码语言:javascript
复制
  final BlockingQueue<Message> blockingQueue = new LinkedBlockingQueue<Message>();

哪里

代码语言:javascript
复制
public class Message {
    private String author;
    private String text;
        .......
//setters and getters
.....
}

我有一个生产者,它把消息放入队列。

现在我的目标是创建消费者,它将能够从队列中提取特定作者的特定消息?有可能吗?

如果不是,有什么可以替代BlockingQueue呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-20 01:40:12

如果字符串是author,则可以使用ConcurrentMap<String,BlockingQueue<Message>>

代码语言:javascript
复制
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。

票数 4
EN

Stack Overflow用户

发布于 2012-03-20 01:35:21

这当然是可能的,假设您可以灵活地处理到达队列前面的元素,这些元素与您的标准不匹配。

一种简单的方法是这样的

代码语言:javascript
复制
while (true) {
   Message message = blockingQueue.take();
   if ( !message.author.equals(expectedAuthor) ) {
      continue;
   }
}

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

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

代码语言:javascript
复制
Map<String, BlockingQueue<Message>> authorQueues;
BlockingQueue<Message> allMessages;

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

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

票数 3
EN

Stack Overflow用户

发布于 2012-03-20 01:34:32

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9774937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档