wake-up-neo.net

Wie funktioniert ConcurrentHashMap intern?

Ich las die offizielle Oracle-Dokumentation zu Concurrency in Java und fragte mich, was der Unterschied zwischen einer Collection sein könnte, die von zurückgegeben wurde

public static <T> Collection<T> synchronizedCollection(Collection<T> c);

und zum Beispiel mit a 

ConcurrentHashMap. Ich gehe davon aus, dass ich synchronizedCollection(Collection<T> c) für eine HashMap verwende. Ich weiß, dass eine synchronisierte Sammlung im Allgemeinen nur ein Dekorateur für meine HashMap ist. Es ist also offensichtlich, dass eine ConcurrentHashMap etwas anderes in ihrem Inneren hat. Haben Sie Informationen zu diesen Implementierungsdetails?

Edit: Ich habe festgestellt, dass der Quellcode öffentlich verfügbar ist:ConcurrentHashMap.Java

39
Adam Arold

Ich würde die source von ConcurrentHashMap lesen, da es im Detail ziemlich kompliziert ist. Kurz gesagt hat es

  • Mehrere Partitionen, die unabhängig voneinander gesperrt werden können. (16 standardmäßig)
  • Verwenden gleichzeitiger Sperrvorgänge zur Thread-Sicherheit statt synchronisiert.
  • Hat Thread-sichere Iteratoren. Die Iteratoren von synchronizedCollection sind nicht threadsicher.
  • Legt die internen Sperren nicht offen. synchronizedCollection funktioniert.
40
Peter Lawrey

ConcurrentHashMap ist der Java.util.HashTable-Klasse sehr ähnlich, außer dass ConcurrentHashMap eine bessere Parallelität bietet als HashTable oder synchronizedMap. ConcurrentHashMap sperrt die Map nicht, während Sie davon lesen. Darüber hinaus sperrt ConcurrentHashMap nicht das gesamte Map-Objekt, wenn darauf geschrieben wird. Es sperrt nur den Teil von Map, in den intern geschrieben wird. 

Ein weiterer Unterschied ist, dass ConcurrentHashMap ConcurrentModificationException nicht auslöst, wenn ConcurrentHashMap während der Iteration geändert wird. Iterator kann nicht von mehr als einem Thread verwendet werden, wohingegen synchronizedMapConcurrentModificationException werfen kann. 

22
amicngh

Dies ist der Artikel, der mir geholfen hat, es zu verstehen Warum ConcurrentHashMap besser ist als Hashtable und genauso gut wie eine HashMap

Hashtables bieten gleichzeitigen Zugriff auf ihre Einträge. Die gesamte Map ist gesperrt, um jegliche Art von Operationen auszuführen. Während dieser Aufwand in einer Webanwendung unter normalen .__ ignoriert werden kann. Last, unter hoher Last kann es zu verzögerten Antwortzeiten und Überforderung Ihres Servers ohne triftigen Grund. 

Hier tritt ConcurrentHashMap ein. Sie bieten alle Funktionen von Hashtable mit einer Leistung fast so gut wie eine HashMap . ConcurrentHashMaps erreichen dies durch einen sehr einfachen Mechanismus. Anstelle einer Map-weiten Sperre enthält die Sammlung eine Liste mit 16 standardmäßig gesperrt. Jede davon wird zum Schutz (oder Sperren) einer einzelnen .__ verwendet. Eimer der Karte. Dies bedeutet effektiv, dass 16 Threads __ ändern können. die Sammlung auf einmal (sofern sie alle an verschiedenen Buckets arbeiten). Tatsächlich wird von diesem Vorgang keine Operation ausgeführt Sammlung, die die gesamte Karte sperrt. Die Parallelitätsebene von collection, die Anzahl der Threads, die gleichzeitig geändert werden können ohne zu blockieren, kann erhöht werden. Eine höhere Zahl bedeutet jedoch mehr Aufwand für die Pflege dieser Sperrliste.

15
gresdiplitude

Die "Skalierbarkeitsprobleme" für Hashtable sind in Collections.synchronizedMap(Map) auf die gleiche Weise vorhanden - sie verwenden eine sehr einfache Synchronisation, was bedeutet, dass nur ein Thread gleichzeitig auf die Karte zugreifen kann.

Dies ist bei einfachen Einfügungen und Suchvorgängen kein großes Problem (es sei denn, Sie tun dies extrem intensiv), wird jedoch zu einem großen Problem, wenn Sie die gesamte Map durchlaufen müssen, was für eine große Map lange Zeit in Anspruch nehmen kann Ein Thread tut das, alle anderen müssen warten, wenn sie etwas einfügen oder nachschlagen wollen.

Die Variable ConcurrentHashMap verwendet sehr ausgefeilte Techniken, um den Bedarf an Synchronisation zu reduzieren und parallelen Lesezugriff für mehrere Threads ohne Synchronisation zu ermöglichen. Darüber hinaus stellt sie einen Iterator bereit, der keine Synchronisation erfordert und sogar die Änderung der Map während der Interation zulässt (dies garantiert jedoch keine Garantie) ob Elemente, die während der Iteration eingefügt wurden, zurückgegeben werden oder nicht).

5
MayurB

Zurückgegeben von synchronizedCollection () ist ein Objekt, dessen Methoden auf this synchronisiert sind, sodass alle gleichzeitigen Vorgänge auf einem solchen Wrapper serialisiert werden. ConcurrentHashMap ist ein wirklich gleichzeitiger Container mit feinkörnigem Verschluss, der so optimiert ist, dass die Konkurrenz so gering wie möglich gehalten wird. Schauen Sie sich den Quellcode an und Sie werden sehen, was sich darin befindet.

3
bobah

ConcurrentHashMap implementiert ConcurrentMap, die die Parallelität bereitstellt . Die Iteratoren sind intern so konzipiert, dass sie jeweils nur von einem Thread verwendet werden, der die Synchronisierung aufrechterhält .. Diese Zuordnung wird häufig in der Parallelität verwendet.

0
Manish Joshi