Ho un HashMap
private Map<K, V> map = new HashMap<>();
Un metodo metterà coppia K-V in esso chiamando put(K,V)
.
L'altro metodo vuole estrarre un insieme di elementi casuali dai suoi valori:
int size = map.size(); // size > 0
V[] value_array = map.values().toArray(new V[size]);
Random rand = new Random();
int start = rand.nextInt(size); int end = rand.nextInt(size);
// return value_array[start .. end - 1]
I due metodi vengono chiamati in due differenti thread concorrenti.
Errore:
ho ottenuto un errore di ConcurrentModificationException
:
at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$ValueIterator.next(Unknown Source)
at java.util.AbstractCollection.toArray(Unknown Source)
Sembra che il metodo toArray()
in un thread è in realtà scorrere il HashMap e una modifica put()
in altro thread si verifica.
Question: How to avoid "ConcurrentModificationException" while using HashMap.values().toArray() and HashMap.put() in concurrent threads?
Directly avoiding usingvalues().toArray()
in the second method is also OK.
eseguire il codice che accede al 'map' in un blocco di sincronizzazione:' sincronizzazione (mappa) {...} '' – Titus
sincronizzazione (mappa) {..} 'dovrebbe funzionare (se lo si applica in tutto il mondo). Collections.synchronizedMap non funzionerà. vedere http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedMap%28java.util.Map%29 – Thilo