In Javadoc für ConcurrentHashMap ist Folgendes:
Abrufvorgänge (einschließlich get) werden im Allgemeinen nicht blockiert und können sich daher mit Aktualisierungsvorgängen (einschließlich put und remove) überschneiden. Abrufe spiegeln die Ergebnisse der zuletzt abgeschlossenen Aktualisierungsvorgänge wider, die bei ihrem Beginn ausgeführt wurden. Bei aggregierten Vorgängen wie putAll und clear können gleichzeitige Abfragen das Einfügen oder Entfernen nur einiger Einträge widerspiegeln. In ähnlicher Weise geben Iteratoren und Aufzählungen Elemente zurück, die den Status der Hash-Tabelle zu einem bestimmten Zeitpunkt oder seit der Erstellung des Iterators / der Aufzählung widerspiegeln. Sie lösen keine ConcurrentModificationException aus. Iteratoren können jedoch jeweils nur von einem Thread verwendet werden.
Was heißt das? Was passiert, wenn ich versuche, die Karte mit zwei Threads gleichzeitig zu iterieren? Was passiert, wenn ich einen Wert während der Iteration in die Karte einfüge oder aus der Karte entferne?
ConcurrentModificationException
Weile Zeit, einConcurrentHashMap
, warum?Mit dieser Klasse können Sie zwei Zugriffsthreads und einen Mutationstest für die gemeinsam genutzte Instanz von
ConcurrentHashMap
: testen.Es wird keine Ausnahme ausgelöst.
Das Teilen desselben Iterators zwischen Accessor-Threads kann zu einem Deadlock führen:
Sobald Sie beginnen, dasselbe für
Iterator<Map.Entry<String, String>>
Accessor- und Mutator-Threads freizugeben, werdenjava.lang.IllegalStateException
s angezeigt.quelle
Dies bedeutet, dass Sie ein Iteratorobjekt nicht für mehrere Threads freigeben sollten. Das Erstellen mehrerer Iteratoren und deren gleichzeitige Verwendung in separaten Threads ist in Ordnung.
quelle
Dies könnte Ihnen einen guten Einblick geben
Was das betrifft:
Dies bedeutet, dass die Verwendung von Iteratoren, die von ConcurrentHashMap in zwei Threads erstellt wurden, zwar sicher ist, jedoch zu einem unerwarteten Ergebnis in der Anwendung führen kann.
quelle
Dies bedeutet, dass Sie nicht versuchen sollten, denselben Iterator in zwei Threads zu verwenden. Wenn Sie zwei Threads haben, die über die Schlüssel, Werte oder Einträge iterieren müssen, sollten sie jeweils ihre eigenen Iteratoren erstellen und verwenden.
Es ist nicht ganz klar, was passieren würde, wenn Sie gegen diese Regel verstoßen würden. Sie könnten nur verwirrendes Verhalten bekommen, genauso wie Sie es tun, wenn (zum Beispiel) zwei Threads versuchen, von der Standardeingabe zu lesen, ohne sie zu synchronisieren. Sie könnten auch ein nicht threadsicheres Verhalten erhalten.
Wenn die beiden Threads jedoch unterschiedliche Iteratoren verwendeten, sollte es Ihnen gut gehen.
Das ist ein separates Problem, aber der von Ihnen zitierte Javadoc-Abschnitt beantwortet es angemessen. Grundsätzlich sind die Iteratoren threadsicher, es ist jedoch nicht definiert, ob die Auswirkungen gleichzeitiger Einfügungen, Aktualisierungen oder Löschungen in der vom Iterator zurückgegebenen Reihenfolge von Objekten angezeigt werden. In der Praxis hängt es wahrscheinlich davon ab, wo in der Karte die Aktualisierungen stattfinden.
quelle