HashMap vs. ConcurrentHashMap Vs. SynchronizedMap – Wie eine HashMap in Java synchronisiert werden kann

Veröffentlicht: 2015-01-29

Crunchify ConcurrentHashMap Vs. SynchronizedMap-Beispiel HashMap ist eine sehr mächtige Datenstruktur in Java. Wir verwenden es täglich und in fast allen Anwendungen. Es gibt einige Beispiele, die ich zuvor geschrieben habe, wie man Threadsafe-Cache implementiert, wie man Hashmap in Arraylist konvertiert?

Wir haben Hashmap in beiden obigen Beispielen verwendet, aber das sind ziemlich einfache Anwendungsfälle von Hashmap. HashMap is a non-synchronized Sammlungsklasse.

Haben Sie eine der folgenden Fragen?

  • Was ist der Unterschied zwischen ConcurrentHashMap und Collections.synchronizedMap(Map)?
  • Was ist der Unterschied zwischen ConcurrentHashMap und Collections.synchronizedMap(Map) in Bezug auf die Leistung?
  • ConcurrentHashMap vs. Collections.synchronizedMap()
  • Beliebte HashMap- und ConcurrentHashMap-Interviewfragen

In diesem Tutorial werden wir alle oben genannten Abfragen durchgehen und begründen, why and how wir Hashmap synchronisieren können.

Warum?

Das Map-Objekt ist ein assoziativer Container, der Elemente speichert, die durch eine Kombination aus einem eindeutig identifizierenden key und einem zugeordneten value gebildet werden. Wenn Sie eine sehr parallele Anwendung haben, in der Sie Schlüsselwerte in verschiedenen Threads ändern oder lesen möchten, ist es ideal, Concurrent Hashmap zu verwenden. Bestes Beispiel ist Producer Consumer, der gleichzeitiges Lesen/Schreiben verarbeitet.

Was bedeutet also die Thread-sichere Karte? Wenn multiple threads gleichzeitig auf eine Hash-Map zugreifen und mindestens einer der Threads die Map strukturell verändert, must be synchronized externally , um eine inkonsistente Ansicht der Inhalte zu vermeiden.

Wie?

Es gibt zwei Möglichkeiten, HashMap zu synchronisieren

  1. SynchronizedMap()-Methode von Java-Sammlungen
  2. Verwenden Sie ConcurrentHashMap

ConcurrentHashMap

  • Sie sollten ConcurrentHashMap verwenden, wenn Sie in Ihrem Projekt eine sehr hohe Parallelität benötigen.
  • Es ist Thread-sicher, ohne die whole map zu synchronisieren.
  • Das Lesen kann sehr schnell erfolgen, während das Schreiben mit einer Sperre erfolgt.
  • Es gibt keine Sperre auf Objektebene.
  • Die Sperrung erfolgt auf Hashmap-Bucket-Ebene mit einer viel feineren Granularität.
  • ConcurrentHashMap löst keine ConcurrentModificationException aus, wenn ein Thread versucht, sie zu ändern, während ein anderer darüber iteriert.
  • ConcurrentHashMap verwendet eine Vielzahl von Sperren.

SynchronizedHashMap

  • Synchronisation auf Objektebene.
  • Jeder Lese-/Schreibvorgang muss eine Sperre erwerben.
  • Das Sperren der gesamten Sammlung ist ein Leistungsmehraufwand.
  • Dies gibt im Wesentlichen nur einem Thread Zugriff auf die gesamte Karte und blockiert alle anderen Threads.
  • Es kann zu Konflikten kommen.
  • SynchronizedHashMap gibt Iterator zurück, der bei gleichzeitiger Änderung schnell fehlschlägt.

Schauen wir uns nun den Code an

  1. Erstellen Sie die Klasse CrunchifyConcurrentHashMapVsSynchronizedHashMap.java
  2. Erstellen Sie ein Objekt für jede HashTable, SynchronizedMap und CrunchifyConcurrentHashMap
  3. Fügen Sie 500.000 Einträge von Map hinzu und rufen Sie sie ab
  4. Start- und Endzeit messen und Zeit in Millisekunden anzeigen
  5. Wir werden ExecutorService verwenden, um 5 threads parallel auszuführen

Hier ist ein Java-Code:

  • shutdown() bedeutet, dass der Executor-Dienst keine eingehenden Aufgaben mehr annimmt.
  • awaitTermination() wird nach einer Anforderung zum Herunterfahren aufgerufen.

Daher müssen Sie zuerst den serviceExecutor herunterfahren und dann blockieren und warten, bis die Threads beendet sind.

Ergebnis der Eclipse-Konsole: