Does a HashMap with a getAndWait() method exist? E.g. a BlockingConcurrentHashMap implementation?

帅比萌擦擦* 提交于 2019-11-29 18:45:38

问题


Many threads may populate a HashMap, in some cases I need to wait (block) until an object exists in the HashMap, such as:

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

Wondering if such a thing exists already, I hate re-inventing wheels.


回答1:


As far as I know, there is no 'Transfer Map' available. Though the creation of one in theory isn't too difficult.

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;
   }
  }

There are obvious exclusions in this class. Not to mentioned the lock coarsening; needless to say it won't perform great, but you should get the idea of what is going on




回答2:


Blockingmap4j will suit your requirement just right.
You can find it at https://github.com/sarveswaran-m/blockingMap4j/wiki/
Since granular locks are used in the implementation, performance will not be severely degraded.

PS
This is a rather late answer on a question that is 2 years old. Since, there is no way to send a private message to the author of the question, am replying here.




回答3:


Improvement on John's impl, with aimed notify(), instead of "thundering herd", which is especially bad when nobody is waiting on an inserted key

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



回答4:


You can populate your Hashtable with java.util.concurrent.FutureTask<ObjReturned>s at the start with all the tasks you need to compute. You then use a thread pool to start executing your FutureTasks. You can get your results asynchronously with ObjReturned obj = hashtable.get(key).get(), which will wait if the FutureTask in question is not done yet.

You probably don't want one single thread to retrieve the results since it might wait on the task that will turn out to finish last. You could have multiple retrieval threads, or you could cycle through the keys when you wait too long for one task (there is a method FutureTask.get(waitTime, timeUnit)).




回答5:


I'm not sure what your question is. Do you want to wait for the value when it is not in the map? You want the producer-consumer pattern of BlockingQueue on a map. If it is that I don't know anything similar in the JRE or anywhere else.

Google guava MapMaker allows you to make a computing map, that is a Map that creates the value if it does not exist by using a factory with type Function<Key, Value>. If several threads reach that situation at the same time one creates the value and the rest blocks waiting for it. I know it's not producer-consumer but is what I can offer.



来源:https://stackoverflow.com/questions/6389122/does-a-hashmap-with-a-getandwait-method-exist-e-g-a-blockingconcurrenthashma

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!