1

次のblockingQueueがあります。

  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

基準に一致しないキューの先頭に到達する要素に何が起こるかについて柔軟であると仮定すると、それは確かに可能です。

簡単な方法の1つは、次のようなものです。

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 に答える