2012-06-19 19 views
9

は今、私はプロデューサ/コンシューマスレッドを作成しようとしています、生産者スレッドは、文字のすべての可能な組み合わせを経由して、それぞれのMD5ハッシュを作成します。次に、各組み合わせとそのハッシュはHashMap<String,String>に入れられます。今私の消費者のスレッドで私は消費者のスレッドがQueueのようにATCが、それでも私にpoll()を呼び出すときに組み合わせ、そのハッシュの両方を見ての機能を与えるため、値を削除poll()などを呼び出すことができますので、ハッシュマップ上Queue<>コレクションを使用できるようにしたいですこれをどうやってやりますか?私はHashMapを持っていますが、キューを作成する方法やキューに入れる方法は知られていません。おかげさまで HashMapのキューを作成することは可能ですか?

答えて

7

あなたはあなたのコードのスレッドの安全性を処理せずにHashMapを使用しないでください。それ以外の場合は、ライブロックで終了することがあります。

キーが挿入された順序でマップを反復できるようにするには、LinkedHashMapを使用できます。

Map m = Collections.synchronizedMap(new LinkedHashMap(...)); 

プロデューサーは、この(何も特別な)のようなエントリをプッシュします:消費者はこのようなエントリポーリングします

m.put(key, object) 

を:

while (someCondition) { 
    Map.Entry nextEntry = null; 

    // This block is equivalent to polling 
    { 
     synchronized(s) { 
      Iterator i = s.iterator(); // Must be in the synchronized block 
      if (i.hasNext()) { 
       nextEntry = i.next(); 
       i.remove(); 
      } 
     } 
    } 

    if (nextEntry != null) { 
     // Process the entry 
     ... 
    } else { 
     // Sleep for some time 
     ... 
    } 
    // process 
} 
+0

これは魅力的なものでした。ありがとうございました。 –

5

LinkedHashMapタイプHashMapQueueの組み合わせのようなものである - それは、キー/値ペアを格納するだけでなく、それらが挿入された順序を覚えています。これはまさにあなたが探しているタイプかもしれません。そこには明示的なpoll()機能はありませんが、あなたはLinkedHashMap Iteratorを取得する場合、あなたは彼らが追加された順序で要素を訪問します。おそらく、次のような関数を書くことができます:

public <KeyType, ValueType> KeyType first(LinkedHashMap<KeyType, ValueType> map) { 
    assert !map.isEmpty(); 
    return map.iterator().next(); 
} 

これは最初の要素を返すでしょう。適切に同期するようにしてください。

また、Queueの中にキー/値のペアを格納することを検討するには、ヘルパークラスPairを定義し、Pairをキューに格納します。

希望すると便利です。

+0

ニースを、ので、彼はちょうどに、いくつかのSyncObjectが必要になりますコンシューマ側でLinkedHashMapから読み込むことが可能なときにシグナルを送出します。 –

+0

こんにちは、のLinkedHashMapはスレッドセーフではありません、それはタイプ待ち行列のではありません。 – sperumal

+0

@ sperumal-私はこれらのいずれかが事実であると断言したことはありません。私は、OPが同期コードを供給すると仮定しました。また、 'Queue'型​​でなければならないという要件はないと私は信じています。 OPの質問はこれを決して言及しない。これが要件である場合、このアプローチは間違いなく機能しません。 – templatetypedef

4

私はあなたのentrySetのキューを作成示唆 -

Queue<EntrySet<String,String>> queue = new SynchronousQueue<EntrySet<String,String>>(); 
for (EntrySet<String,String> entry:map.entrySet()) { 
    queue.add(entry); 
} 

あなたは要素、およびなどLinkedBlockingQueueなどの非空の場合のみprdocuerの待機を置くことができますされ、キューの別のタイプを使用して検討することができます。
プロデューサは、次いで、必要に応じて、オブジェクトのentrySetに基づいてマップを再構成することができるであろう。

+0

これは良い方法のように思えます。ありがとう、私はそれを試してみましょう。 1つの質問は、このスレッドセーフですか? –

関連する問題