Ich habe eine HashMap
private Map<K, V> map = new HashMap<>();
Eine Methode wird durch den Aufruf put(K,V)
hinein K-V Paar setzen.
Die andere Methode will von ihren Werten einen Satz von Zufallselementen extrahieren:
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]
Die beiden Methoden sind in zwei verschiedenen gleichzeitige Threads bezeichnet.
Fehler:
Ich bekam einen ConcurrentModificationException
Fehler:
at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
at java.util.HashMap$ValueIterator.next(Unknown Source)
at java.util.AbstractCollection.toArray(Unknown Source)
Es scheint, dass die toArray()
Methode in einem Thread tatsächlich über die HashMap iteriert und eine put()
Modifikation in anderem Thread tritt ein.
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.
den Code ausführen, der die 'map' in einem Synchronisierungsblock zugreift:' synchronisieren (Karte) {...} '' – Titus
synchronize (Karte) {..} 'funktionieren sollte (wenn Sie es überall anwenden). Collections.synchronizedMap funktioniert nicht. siehe http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedMap%28java.util.Map%29 – Thilo