2012-06-19 15 views
9

En este momento estoy tratando de crear un hilo productor/consumidor, el hilo del productor pasa por todas las posibles combinaciones de letras y crea sus respectivos hash MD5. Entonces cada combinación y su hash se ponen en el HashMap<String,String>. Ahora en mi hilo de consumo quiero poder usar la colección Queue<> en el hashmap para que mi hilo de consumidor pueda llamar al poll(), etc., eliminando así los valores atc como Queue pero aun así me da la capacidad de ver tanto la combinación como su hash al llamar al poll() ¿Cómo voy a hacer esto? Tengo el HashMap pero no sé cómo 'hacer' o lanzarlo como una Cola. Gracias.¿Es posible crear una cola para el conjunto de HashMap?

Respuesta

7

No debe usar un HashMap sin manejar la seguridad de subprocesos de su código. De lo contrario, puede terminar con un Live-lock.

Para poder iterar su Mapa con el orden en que se insertaron las claves, puede usar un LinkedHashMap.

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

El productor empujaría entradas como esto (nada especial):

m.put(key, object) 

que el consumidor pueda sondear las entradas de la siguiente manera:

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

Gracias, trabajó un encanto y fue rápido, fácil y claro de implementar –

5

El tipo LinkedHashMap es como una combinación de un HashMap y una Queue - que almacena pares clave/valor, pero también recuerda el orden en el que fueron insertados. Este podría ser exactamente el tipo que estás buscando. No hay una función explícita poll(), pero si obtiene un iterador sobre el LinkedHashMap, podrá visitar los elementos en el orden en que se agregaron. Probablemente pueda escribir una función como esta:

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

que le devolverá el primer elemento. Solo asegúrese de sincronizar apropiadamente.

Alternativamente, usted podría considerar simplemente almacenar pares clave/valor dentro de un Queue mediante la definición de una clase de ayuda Pair y luego almacenar Pair s en la cola.

Espero que esto ayude!

+0

Niza, por lo que sólo se necesita un poco de SyncObject a señal cuando es posible leer desde LinkedHashMap en el lado del consumidor. –

+0

Hola, LinkedHashMap no es seguro para subprocesos y no es del tipo Queue. – sperumal

+0

@ sperumal- Nunca insinué que ninguno de estos fuera el caso. Supuse que el OP suministraría el código de sincronización. Además, no creo que exista ningún requisito que deba ser de tipo 'Queue'; la pregunta del OP nunca menciona esto. Si esto es un requisito, entonces este enfoque definitivamente no funcionará. – templatetypedef

4

que sugieren que crear una cola de entrySet -

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

Usted puede considerar el uso de otro tipo de cola, lo que le permite poner los elementos, y sólo espera el prdocuer en caso de no vacía como LinkedBlockingQueue.
El productor podrá entonces recomponer un mapa basado en los objetos EntrySet, si es necesario.

+0

Hmm esto parece un buen método. Gracias, lo intentaré. Una pregunta, ¿es seguro este hilo? –

Cuestiones relacionadas