Comment éviter HashMap “ConcurrentModificationException” lors de la manipulation de valeurs de()` et `()` dans les threads simultanés?

Code:

J'ai une table de hachage

private Map<K, V> map = new HashMap<>();

Une méthode sera mis K-V paire en en appelant put(K,V).

L'autre méthode veut extraire un ensemble d'éléments aléatoires à partir de ses valeurs:

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]

Les deux méthodes sont appelées dans deux différents threads simultanés.


Erreur:

J'ai eu un ConcurrentModificationException erreur:

at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$ValueIterator.next(Unknown Source)
at java.util.AbstractCollection.toArray(Unknown Source)

Il semble que la toArray() méthode dans un thread est en fait une itération sur la table de hachage et un put() modification dans d'autres thread se produit.

Question: Comment éviter de "ConcurrentModificationException" tout en utilisant une table de hachage.les valeurs de().toArray() et de la table de hachage.put() dans les threads simultanés?
Directement en évitant l'utilisation de values().toArray() dans la deuxième méthode est également OK.

Exécuter le code qui accède à la map dans un synchroniser bloc: synchronize(map){...}
synchronize(map){..} devrait fonctionner (si vous l'appliquer partout). Les Collections.synchronizedMap ne fonctionne pas. voir docs.oracle.com/javase/7/docs/api/java/util/...

OriginalL'auteur hengxin | 2014-10-29