¿Existe un método hashmap con un método getandwait ()? ¿Por ejemplo, una implementación de BloquingConcurrentHashmap?

StackOverflow https://stackoverflow.com/questions/6389122

Pregunta

Muchos hilos pueden poblar un HashMap, en algunos casos, necesito esperar (bloquear) hasta que exista un objeto en el hashmap, como:

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

Me pregunto si tal cosa ya existe, odio reinventar ruedas.

¿Fue útil?

Solución

Hasta donde yo sé, no hay 'mapa de transferencia' disponible. Aunque la creación de uno en teoría no es demasiado difícil.

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

Hay exclusiones obvias en esta clase. No mencionar el engrosamiento de la cerradura; No hace falta decir que no funcionará muy bien, pero debes tener la idea de lo que está sucediendo

Otros consejos

BloquingMap4J se adaptará a sus requisitos a la perfección.
Puedes encontrarlo en https://github.com/sarveswaran-m/blockingmap4j/wiki/
Dado que las cerraduras granulares se utilizan en la implementación, el rendimiento no se degradará severamente.

PD
Esta es una respuesta bastante tardía en una pregunta que tiene 2 años. Dado que no hay forma de enviar un mensaje privado al autor de la pregunta, estoy respondiendo aquí.

Mejora en John's Impl, con Aimed notify (), en lugar de "tronero", que es especialmente malo cuando nadie espera una llave insertada

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

Puedes poblar tu Hashtable con java.util.concurrent.FutureTask<ObjReturned>S al comienzo con todas las tareas que necesita calcular. Luego usa un grupo de hilos para comenzar a ejecutar su FutureTasks. Puede obtener sus resultados de forma asincrónica con ObjReturned obj = hashtable.get(key).get(), que esperará si el FutureTask en cuestión aún no se hace.

Probablemente no desee un solo hilo para recuperar los resultados, ya que podría esperar la tarea que resultará finalizar el último. Puede tener múltiples hilos de recuperación, o puede recorrer las claves cuando espere demasiado tiempo para una tarea (hay un método FutureTask.get(waitTime, timeUnit)).

No estoy seguro de cuál es tu pregunta. ¿Quieres esperar el valor cuando no está en el mapa? Desea el patrón del productor-consumidor de Bloquingqueue en un mapa. Si es que no sé nada similar en el JRE o en cualquier otro lugar.

Google Guava Mapmaker le permite hacer un mapa informático, ese es un mapa que crea el valor si no existe mediante el uso de una función de fábrica con tipou003CKey, Value> . Si varios hilos alcanzan esa situación al mismo tiempo, uno crea el valor y los bloques de descanso lo esperan. Sé que no es consumidor de productores, pero es lo que puedo ofrecer.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top