ConcurrentHashMap vs Synchronized HashMap


148

Was ist der Unterschied zwischen der Verwendung der Wrapper-Klasse SynchronizedMapfür a HashMapund ConcurrentHashMap?

Kann es das nur ändern, HashMapwährend es iteriert wird ( ConcurrentHashMap)?

Antworten:


120

Synchronisiert HashMap:

  1. Jede Methode wird mithilfe einer Sperre auf Objektebene synchronisiert. Die Methoden get und put auf synchMap erhalten also eine Sperre.

  2. 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.

  1. Auf Objektebene gibt es keine Sperrung. Die Sperrung ist viel feiner. Für a ConcurrentHashMapkönnen sich die Sperren auf einer Hashmap-Bucket-Ebene befinden.

  2. 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.

  3. ConcurrentHashMapwirft kein a, ConcurrentModificationExceptionwenn 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.


7
Was ist der Unterschied zwischen Hashtableund Synchronized HashMap?
Roottraveller

1
Welche empfehlen Sie zwischen einer ConcurrentHashMap und einer synchronisierten HashMap?
Blunderchips

2
Es ist erwähnenswert, dass ConcurrentHashMapdas 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.
Andrii Lisun

1
@roottraveller für Hashtable und synchronisierte HashMap stackoverflow.com/questions/8875680/…
Narendra Jaggi

89

Die kurze Antwort:

Beide Maps sind threadsichere Implementierungen der MapSchnittstelle. ConcurrentHashMapwird 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 ConcurrentHashMapist eine sehr gute Lektüre. Sehr empfehlenswert.


1
Was ist das dann? HashMap: Beachten Sie, dass diese Implementierung nicht synchronisiert ist, um einen versehentlichen nicht synchronisierten Zugriff auf die Karte zu verhindern: Map m = Collections.synchronizedMap(new HashMap(...)); docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
X-HuMan

5
"Brian Goetz 'Artikel ... ist eine sehr gute Lektüre." - Und noch mehr ist sein Buch "Java Concurrency in Practice".
Alex Fedulov

31

ConcurrentHashMapist threadsicher, ohne die gesamte Map zu synchronisieren. Das Lesen kann sehr schnell erfolgen, während das Schreiben mit einer Sperre erfolgt.


18

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.

  1. synchronizedHashmap

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.

  1. ConcurrentHashMap

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.


Sehr schöne Erklärung Vielen Dank
amoljdv06

11

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.


7

ConcurrentHashMapverwendet einen feinkörnigeren Verriegelungsmechanismus, der bekanntermaßen lock strippingeinen größeren Grad an gemeinsamem Zugriff ermöglicht. Aufgrund dessen bietet es eine bessere Parallelität und Skalierbarkeit .

Auch die zurückgegebenen Iteratoren ConcurrentHashMapsind schwach konsistent anstatt der von Synchronized HashMap verwendeten Fail-Fast-Technik .


3

Methoden zum SynchronizedMapHalten der Sperre für das Objekt, wohingegen ConcurrentHashMapes ein Konzept des "Lock Striping" gibt, bei dem Sperren stattdessen für Eimer des Inhalts gehalten werden. Dadurch verbesserte Skalierbarkeit und Leistung.


2

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.


1

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.



0

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.


0

SynchronizedMapund ConcurrentHashMapsind beide Thread - sicher - Klasse und kann in Multi - Thread - Anwendung verwendet werden, der Hauptunterschied zwischen ihnen darüber , wie sie die Thread - Sicherheit erreichen.

SynchronizedMapErlangt die Sperre für die gesamte Map-Instanz, während ConcurrentHashMapdie Map-Instanz in mehrere Segmente unterteilt wird und diese gesperrt werden.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.