Ich lese das Buch Java Concurrecny in der Praxis. Auf Seite 85 Abschnitt 5.2.1 wird über die ConcurrentHashMap und ihre Vorteile gesprochen. In einem Teil behaupten die Bücher jedoch, dass
Die von ConcurrentHashMap zurückgegebenen Iteratoren sind schwach konsistent. Dies bedeutet, dass dieser Iterator gleichzeitige Änderung tolerieren kann, traverses Elemente wie sie existierten, als Iterator konstruiert wurde, und kann (aber nicht garantiert) Änderungen an der Sammlung widerspiegeln nach der Konstruktion des Iterators.
Aus dem Grund, warum ich den ganzen Punkt der Synchronisation in konkurrierenden Programmen verstehe, ist es dem Thread zu erlauben, auf eine gemeinsam genutzte Ressource auf konsistente Weise zuzugreifen, während ConcurrentHashMap dies nicht wirklich erfüllt. Warum dann überhaupt?
Der Punkt ist die Vermeidung Synchronisation, wenn Sie sie nicht brauchen. Wenn es Ihnen nichts ausmacht, in einigen Fällen neue Elemente zu sehen und sie nicht in anderen zu sehen, kann der Iterator von ConcurrentHashMap
erheblich billiger sein als entweder und verhindert, dass andere Threads Elemente hinzufügen, während Sie iterieren oder nehmen einen konsistenten Snapshot, wenn der Iterator erstellt wird.
Wenn Sie also eine Synchronisation und einen konsistenten Iterator benötigen, brauchen Sie eine Alternative - aber wenn Sie dies nicht tun, können Sie den effizienteren Iterator von ConcurrentHashMap
nutzen.
ConcurrentHashMap
soll vertraglich threadsicher sein. Es ist jedoch nicht konsistent über Threads .
Wenn Sie über eine ConcurrentHashMap
iterieren, greift der Iterator eine Kopie der Hash-Map in dem Moment, in dem Sie danach gefragt haben (und diese Kopie wird thread-sicher erstellt) und Sie über diese Kopie iterieren. Und ja, nichts garantiert Ihnen das , während Sie über diese Kopie iterieren , einige Karteneinträge werden nicht entfernt. Aber die Map-Einträge, die auf diese Weise entfernt werden würden, existieren noch in Ihrem Iterator .
Alles hängt davon ab, wie stark Sie konsistent sind. Wenn Sie starke brauchen - als Mutexe oder andere Teilmenge von Operationen bieten würde, was Sie brauchen.
Manchmal benötigen Sie jedoch viel schwächere Anforderungen, aber Sie müssen zum Beispiel eine blockfreie Eigenschaft angeben, um den Durchsatz zu gewährleisten. Auf der anderen Seite benötigen Sie möglicherweise keine Iteratoren oder haben viel schwächere Einschränkungen für sie.
Wenn also alles, was Sie brauchen, eine Karte ist, die über Threads ConcurrentHashMap
geteilt wird (sagen Sie Platz im Theater, wenn die Person es bucht), was Sie brauchen - und es kann viel schneller sein, wenn Sie viele Arbeitsfäden haben, da Sie Mutex-Synchronisation vermeiden. Auf der anderen Seite ist die Geschwindigkeit mit Kosten verbunden - die von Iterator zur Verfügung gestellte Ansicht entspricht nicht dem Zustand der Sammlung bei ihrer Erstellung und sie kann einige nachträglich erzeugte Elemente vermissen (im Allgemeinen in Multiprozessorsystemen ist happens-before
relation schwierig) / p>
Bearbeiten : Als Prinz John Wesley darauf hinwies, dachte ich beim Lesen und Schreiben an ConcurrentSkipListMap
. %Code%. Die meisten Punkte bestehen immer noch mit Ausnahme der Teile, die frei von Sperren sind (sowie alles, was davon kommt, wie garantierter Durchsatz, etc.).
Tags und Links java concurrency concurrenthashmap concurrent-programming