是否存在带有getAndWait()方法的HashMap? 例如BlockingConcurrentHashMap实现?

许multithreading可能会填充HashMap ,在某些情况下我需要等待(阻塞)直到HashMap中存在对象,例如:

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

想知道这样的东西是否已经存在,我讨厌重新发明轮子。

据我所知,没有“转移地图”可用。 虽然在理论上创造一个并不太难。

 public class TransferMap implements Map{ @GuardedBy("lock") private final HashMap backingMap = new HashMap(); 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; } } 

本课程中有明显的排除。 没有提到锁粗化; 不用说它不会表现出色,但你应该知道发生了什么

Blockingmap4j恰好符合您的要求。
您可以在https://github.com/sarveswaran-m/blockingMap4j/wiki/找到它。
由于在实现中使用了粒度锁,因此性能不会严重降低。

PS
对于一个2岁的问题,这是一个相当晚的答案。 因为,没有办法向问题的作者发送私信,我在这里回复。

使用目标notify()改进John的impl,而不是“thundering herd”,当没有人等待插入的密钥时,这尤其糟糕

 HashMap 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 

您可以在开始时使用java.util.concurrent.FutureTask填充您的Hashtable ,其中包含您需要计算的所有任务。 然后使用线程池开始执行FutureTask 。 您可以使用ObjReturned obj = hashtable.get(key).get()异步获取结果,如果尚未完成FutureTask ,它将等待。

您可能不希望单个线程检索结果,因为它可能会等待最后完成的任务。 您可以拥有多个检索线程,或者在等待一个任务的时间过长时可以循环访问密钥(有一个方法FutureTask.get(waitTime, timeUnit) )。

我不确定你的问题是什么。 当它不在地图中时,您是否要等待值? 您想在地图上使用BlockingQueue的生产者 – 消费者模式。 如果是我在JRE或其他任何地方都不知道类似的东西。

Google guava MapMaker允许您创建计算地图,即使用类型为Function 的工厂,如果不存在,则创建该值的Map。 如果多个线程同时达到该情况,则创建该值,其余块等待它。 我知道这不是生产者 – 消费者,而是我能提供的。