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
Ich würde die source von ConcurrentHashMap lesen, da es im Detail ziemlich kompliziert ist. Kurz gesagt hat es
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 synchronizedMap
ConcurrentModificationException
werfen kann.
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.
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).
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.
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.