12

多くのスレッドが を生成する可能性がありHashMap、場合によっては、次のようなオブジェクトが HashMap に存在するまで待機 (ブロック) する必要があります。

BlockingConcurrentHashMap map = new BlockingConcurrentHashMap();
Object x = map.getAndWait(key, 1000);    //(object_to_get, max_delay_ms)

そんなものはもうあるのだろうかと思うと、車輪の再発明は嫌いだ。

4

5 に答える 5

5

私の知る限り、利用可能な「転送マップ」はありません。理論的には作成はそれほど難しくありませんが。

public class TransferMap<K,V> implements Map<K,V>{
  @GuardedBy("lock")
  private final HashMap<K,V> backingMap = new HashMap<K,V>();

  private final Object lock = new Object();
  public V getAndWait(Object key){
     synchronized(lock){
       V value = null;
         do{
            value = backingMap.get(key);

            if(value == null) lock.wait();

         }while(value == null); 
      }
      return value;
     }
   public V put(K key, V value){
      synchronized(lock){
         V value = backingMap.put(key,value);
         lock.notifyAll();
      }
     return value;
   }
  }

このクラスには明らかな除外があります。ロックの粗大化は言うまでもありません。言うまでもなく、パフォーマンスは良くありませんが、何が起こっているのかを理解する必要があります

于 2011-06-17T17:16:46.777 に答える
4

Blockingmap4j は、あなたの要件にぴったり合っています。https://github.com/sarveswaran-m/blockingMap4j/wiki/
で見つけることができます 。実装では粒状ロックが使用されるため、パフォーマンスが大幅に低下することはありません。

PS
これは、2年前の質問に対するかなり遅い回答です。質問の投稿者に個人的なメッセージを送る方法がないので、ここで返信します。

免責事項
私はライブラリの作成者です。

于 2013-05-03T07:57:06.703 に答える
3

計算する必要があるすべてのタスクを最初に with にHashtable入力できます。java.util.concurrent.FutureTask<ObjReturned>次に、スレッド プールを使用してFutureTaskの実行を開始します。問題の処理がまだ完了していないObjReturned obj = hashtable.get(key).get()場合は待機します。FutureTask

最後に終了することが判明したタスクを待機する可能性があるため、単一のスレッドで結果を取得することはおそらく望ましくありません。複数の取得スレッドを使用することも、1 つのタスクを長時間待機するときにキーを循環させることもできます (方法がありますFutureTask.get(waitTime, timeUnit))。

于 2011-06-17T18:28:04.860 に答える
3

John の impl の改善。「雷鳴の群れ」の代わりに目的の notify() を使用。これは、挿入されたキーを誰も待っていない場合に特に悪い

HashMap<K,Object> locks = new HashMap<>();

put(key, value)
    synchronized(locks)
        backingMap.put(key,value);

        lock = locks.get(key);
        if(lock!=null)
            lock.notifyAll();

getAndWait(key)
    // not hard, but pretty verbose
于 2011-06-17T17:30:33.397 に答える
0

あなたの質問が何であるかわかりません。値がマップにないときに値を待ちますか? マップ上で BlockingQueue のプロデューサー/コンシューマー パターンが必要です。JREや他の場所で似たようなことを私が知らないということであれば。

Google guava MapMaker を使用すると、コンピューティング マップを作成できます。これは、Function<Key, Value> 型のファクトリを使用して、値が存在しない場合に値を作成する Map です。複数のスレッドが同時にその状況に到達した場合、1 つのスレッドが値を作成し、残りのスレッドはそれを待機します。私はそれが生産者消費者ではないことを知っていますが、私が提供できるものです.

于 2011-06-17T17:10:27.353 に答える