Was ist der Unterschied zwischen der Verwendung der Wrapper-Klasse SynchronizedMap
für a HashMap
und ConcurrentHashMap
?
Kann es das nur ändern, HashMap
während es iteriert wird ( ConcurrentHashMap
)?
Was ist der Unterschied zwischen der Verwendung der Wrapper-Klasse SynchronizedMap
für a HashMap
und ConcurrentHashMap
?
Kann es das nur ändern, HashMap
während es iteriert wird ( ConcurrentHashMap
)?
Antworten:
Synchronisiert HashMap
:
Jede Methode wird mithilfe einer Sperre auf Objektebene synchronisiert. Die Methoden get und put auf synchMap erhalten also eine Sperre.
Das Sperren der gesamten Sammlung ist ein Leistungsaufwand. Während ein Thread an der Sperre festhält, kann kein anderer Thread die Sammlung verwenden.
ConcurrentHashMap
wurde in JDK 5 eingeführt.
Auf Objektebene gibt es keine Sperrung. Die Sperrung ist viel feiner. Für a ConcurrentHashMap
können sich die Sperren auf einer Hashmap-Bucket-Ebene befinden.
Das Sperren auf niedrigerer Ebene hat zur Folge, dass Sie gleichzeitig Leser und Schreiber haben können, was für synchronisierte Sammlungen nicht möglich ist. Dies führt zu einer viel größeren Skalierbarkeit.
ConcurrentHashMap
wirft kein a, ConcurrentModificationException
wenn ein Thread versucht, es zu ändern, während ein anderer darüber iteriert.
Dieser Artikel Java 7: HashMap vs ConcurrentHashMap ist eine sehr gute Lektüre. Sehr empfehlenswert.
ConcurrentHashMap
das size()
Ergebnis veraltet sein könnte. size()
darf eine Näherung anstelle einer exakten Zählung gemäß dem Buch "Java Concurrency in Practice" zurückgeben. Daher sollte diese Methode sorgfältig angewendet werden.
Die kurze Antwort:
Beide Maps sind threadsichere Implementierungen der Map
Schnittstelle. ConcurrentHashMap
wird für einen höheren Durchsatz in Fällen implementiert, in denen eine hohe Parallelität erwartet wird.
Brian Goetz ' Artikel über die Idee dahinter ConcurrentHashMap
ist eine sehr gute Lektüre. Sehr empfehlenswert.
Map m = Collections.synchronizedMap(new HashMap(...));
docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
ConcurrentHashMap
ist threadsicher, ohne die gesamte Map zu synchronisieren. Das Lesen kann sehr schnell erfolgen, während das Schreiben mit einer Sperre erfolgt.
Wir können Thread-Sicherheit erreichen, indem wir sowohl ConcurrentHashMap als auch synchronizedHashmap verwenden. Aber es gibt einen großen Unterschied, wenn man sich die Architektur ansieht.
Die Sperre wird auf Objektebene beibehalten. Wenn Sie also eine Operation wie put / get ausführen möchten, müssen Sie zuerst die Sperre erwerben. Gleichzeitig dürfen andere Threads keine Operation ausführen. Es kann also immer nur ein Thread damit arbeiten. Die Wartezeit wird hier also länger. Wir können sagen, dass die Leistung im Vergleich zu ConcurrentHashMap relativ niedrig ist.
Die Sperre wird auf Segmentebene beibehalten. Es hat 16 Segmente und behält die Parallelitätsstufe standardmäßig als 16 bei. Auf einmal können 16 Threads mit ConcurrentHashMap arbeiten. Darüber hinaus erfordert der Lesevorgang keine Sperre. So können beliebig viele Threads eine Get-Operation ausführen.
Wenn Thread1 eine Put-Operation in Segment 2 ausführen möchte und Thread2 eine Put-Operation in Segment 4 ausführen möchte, ist dies hier zulässig. Das bedeutet, dass 16 Threads gleichzeitig einen Aktualisierungsvorgang (Put / Delete) für ConcurrentHashMap ausführen können.
Damit die Wartezeit hier kürzer wird. Daher ist die Leistung relativ besser als bei synchronisierter Hashmap.
Beide sind synchronisierte Versionen von HashMap, mit Unterschieden in ihrer Kernfunktionalität und ihrer internen Struktur.
ConcurrentHashMap besteht aus internen Segmenten, die konzeptionell als unabhängige HashMaps angesehen werden können. Alle diese Segmente können bei hohen gleichzeitigen Ausführungen durch separate Threads gesperrt werden. So können mehrere Threads Schlüssel-Wert-Paare von ConcurrentHashMap abrufen / einfügen, ohne sich gegenseitig zu blockieren / darauf zu warten. Dies ist für einen höheren Durchsatz implementiert.
wohingegen
Collections.synchronizedMap () erhalten wir eine synchronisierte Version von HashMap, auf die blockierend zugegriffen wird. Das heißt, wenn mehrere Threads gleichzeitig versuchen, auf synchronizedMap zuzugreifen, können sie Schlüssel-Wert-Paare einzeln synchronisieren / setzen.
ConcurrentHashMap
verwendet einen feinkörnigeren Verriegelungsmechanismus, der bekanntermaßen lock stripping
einen größeren Grad an gemeinsamem Zugriff ermöglicht. Aufgrund dessen bietet es eine bessere Parallelität und Skalierbarkeit .
Auch die zurückgegebenen Iteratoren ConcurrentHashMap
sind schwach konsistent anstatt der von Synchronized HashMap verwendeten Fail-Fast-Technik .
Methoden zum SynchronizedMap
Halten der Sperre für das Objekt, wohingegen ConcurrentHashMap
es ein Konzept des "Lock Striping" gibt, bei dem Sperren stattdessen für Eimer des Inhalts gehalten werden. Dadurch verbesserte Skalierbarkeit und Leistung.
ConcurrentHashMap:
1) Beide Maps sind threadsichere Implementierungen der Map-Schnittstelle.
2) ConcurrentHashMap wird für einen höheren Durchsatz in Fällen implementiert, in denen eine hohe Parallelität erwartet wird.
3) Auf Objektebene gibt es keine Sperrung.
Synchronisierte Hash Map:
1) Jede Methode wird mithilfe einer Sperre auf Objektebene synchronisiert.
ConcurrentHashMap ermöglicht den gleichzeitigen Zugriff auf Daten. Die gesamte Karte ist in Segmente unterteilt.
Lesevorgang dh. get(Object key)
wird auch auf Segmentebene nicht synchronisiert.
Aber Schreiboperationen dh. remove(Object key), get(Object key)
Sperre auf Segmentebene erwerben. Nur ein Teil der gesamten Karte ist gesperrt, andere Threads können weiterhin Werte aus verschiedenen Segmenten lesen, außer einem gesperrten.
SynchronizedMap hingegen erhält die Sperre auf Objektebene. Alle Threads sollten unabhängig vom Betrieb (Lesen / Schreiben) auf den aktuellen Thread warten.
Ein einfacher Leistungstest für ConcurrentHashMap vs Synchronized HashMap
. Der Testablauf ruft put
einen Thread auf und get
drei Threads Map
gleichzeitig. Wie @trshiv sagte, hat ConcurrentHashMap einen höheren Durchsatz und eine höhere Geschwindigkeit, für deren Lesevorgang ohne Sperre. Wenn die Betriebszeiten abgelaufen sind 10^7
, ist ConcurrentHashMap 2x
schneller als Synchronized HashMap.
Gemäß Java Docs
Hashtable und Collections.synchronizedMap (neue HashMap ()) werden synchronisiert. ConcurrentHashMap ist jedoch "gleichzeitig".
Eine gleichzeitige Sammlung ist threadsicher, wird jedoch nicht von einer einzigen Ausschlusssperre gesteuert.
Im speziellen Fall von ConcurrentHashMap sind eine beliebige Anzahl gleichzeitiger Lesevorgänge sowie eine einstellbare Anzahl gleichzeitiger Schreibvorgänge sicher zulässig. "Synchronisierte" Klassen können nützlich sein, wenn Sie den gesamten Zugriff auf eine Sammlung über eine einzige Sperre auf Kosten einer schlechteren Skalierbarkeit verhindern müssen.
In anderen Fällen, in denen erwartet wird, dass mehrere Threads auf eine gemeinsame Sammlung zugreifen, sind "gleichzeitige" Versionen normalerweise vorzuziehen. Und nicht synchronisierte Sammlungen sind vorzuziehen, wenn entweder Sammlungen nicht freigegeben sind oder nur zugänglich sind, wenn andere Sperren vorhanden sind.
SynchronizedMap
und ConcurrentHashMap
sind beide Thread - sicher - Klasse und kann in Multi - Thread - Anwendung verwendet werden, der Hauptunterschied zwischen ihnen darüber , wie sie die Thread - Sicherheit erreichen.
SynchronizedMap
Erlangt die Sperre für die gesamte Map-Instanz, während ConcurrentHashMap
die Map-Instanz in mehrere Segmente unterteilt wird und diese gesperrt werden.
Hashtable
undSynchronized HashMap
?