Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Concurrentmap und Seine Implementierungen | Synchronisierte Collections
Multithreading in Java

bookConcurrentmap und Seine Implementierungen

Praxisbeispiel

Eine Webanwendung verwendet ConcurrentMap, um häufig angeforderte Daten wie Benutzersitzungen zwischenzuspeichern. Verschiedene Threads können gleichzeitig Daten aktualisieren und lesen, was schnellen Zugriff und sichere Operationen gewährleistet.

Unterschiede zu anderen Typen

  • Sicherheit in einer Multi-Thread-Umgebung: ConcurrentMap übernimmt die Synchronisierung der Datenzugriffe automatisch, während diese Aufgabe bei einer herkömmlichen Map manuell erfolgen muss;
  • Effizienz: Ermöglicht das parallele Lesen und Schreiben von Daten, ohne die gesamte Datenstruktur zu sperren.

ConcurrentMap-Implementierungen

ConcurrentHashMap: Unterstützt effizient mehrere Threads, indem die Map in Segmente (Buckets) unterteilt wird. Dadurch können Operationen parallel ausgeführt werden, ohne die gesamte Map zu sperren.

Syntax

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<>();

ConcurrentHashMap in Java unterteilt Daten in mehrere Buckets, von denen jeder durch einen eigenen Monitor verwaltet wird. Diese Struktur ermöglicht es verschiedenen Threads, Daten aus unterschiedlichen Buckets gleichzeitig zu lesen oder zu verändern, was die Leistung verbessert.

Threads können parallel auf Buckets zugreifen, wodurch Sperren reduziert und Datenrennen vermieden werden.

Jeder Bucket enthält Datensätze in Form von Schlüssel-Wert-Paaren, die als verkettete Listen organisiert sein können.

ConcurrentSkipListMap: Eine auf Skip-List basierende Implementierung, die eine sortierte Schlüsselreihenfolge unterstützt. Bietet schnelle Einfügung, Löschung und Datenzugriff in einer Multithread-Umgebung.

Syntax

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentSkipListMap = new ConcurrentSkipListMap<>();

📝Einfügen: Wenn ein neues Element zu ConcurrentSkipListMap hinzugefügt wird, beginnt es auf der untersten Ebene. Anschließend steigt es durch die Ebenen auf, bis es dort platziert ist, wo seine Schlüssel und Werte in der richtigen Reihenfolge sind.

🔍Suche: Um ein Element anhand des Schlüssels zu finden, beginnt ConcurrentSkipListMap am Kopfknoten der obersten Ebene. Es folgt den Zeigern, bis es einen Knoten mit einem Schlüssel findet, der gleich oder größer als der Suchschlüssel ist.

❌Löschen: Um ein Element aus der ConcurrentSkipListMap zu entfernen, wird es zunächst aus der untersten Ebene entfernt. Anschließend wird es durch die Ebenen nach unten verschoben, bis es aus der Position entfernt ist, an der seine Schlüssel und Werte korrekt angeordnet sind.

Beispiel für die Verwendung von ConcurrentMap im Code

Hauptmethoden

putIfAbsent(K key, V value): Fügt ein Schlüssel-Wert-Paar zur Map hinzu, nur wenn der Schlüssel noch nicht vorhanden ist.

Main.java

Main.java

copy
123
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.putIfAbsent("a", 1); // Adds the pair ("a", 1) to the map, as "a" is not already present map.putIfAbsent("a", 2); // Does not change the value, as "a" is already present in the map

remove(Object key, Object value): Entfernt das Schlüssel-Wert-Paar, wenn der Schlüssel dem angegebenen Wert zugeordnet ist.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.remove("a", 1); // Removes the pair ("a", 1), as "a" is mapped to value 1 map.remove("a", 2); // Does nothing, as "a" is not mapped to value 2

replace(K key, V value): Ersetzt den Eintrag für einen Schlüssel nur, wenn diesem aktuell ein Wert zugeordnet ist.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.replace("a", 2); // Replaces the value 1 with 2 for key "a" map.replace("b", 3); // Does nothing, as "b" is not present

compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction): Berechnet einen neuen Wert für den angegebenen Schlüssel mithilfe der bereitgestellten Remapping-Funktion, was das Erstellen eines neuen Werts, das Ändern oder das Entfernen des bestehenden Werts umfassen kann.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.compute("a", (k, v) -> v == null ? 1 : v + 1); // Increases the value for key "a" by 1 map.compute("b", (k, v) -> v == null ? 1 : v + 1); // Sets the value to 1 for new key "b"

merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction): Führt den angegebenen Wert mit dem vorhandenen Wert zusammen, der dem Schlüssel zugeordnet ist, indem die bereitgestellte Remapping-Funktion verwendet wird, die bei der Datenaggregation unterstützt.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.merge("a", 2, Integer::sum); // Sums the current value (1) with the new value (2), resulting in 3 map.merge("b", 2, Integer::sum); // Sets the value to 2 for new key "b"

getOrDefault(Object key, V defaultValue) – gibt den Wert zurück, der dem angegebenen Schlüssel zugeordnet ist, oder den Standardwert, falls der Schlüssel nicht vorhanden ist.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); int value1 = map.getOrDefault("a", 0); // Returns 1, as "a" is present int value2 = map.getOrDefault("b", 0); // Returns 0, as "b" is not present

😔 Einschränkungen

Ein potenzieller Nachteil ist die Instabilität der Reihenfolge, da einige Implementierungen während der Iteration keine Reihenfolge der Elemente garantieren. Zusätzlich kann es eine eingeschränkte Unterstützung für bestimmte Operationen geben; beispielsweise werden atomare bedingte Aktualisierungen in einigen Implementierungen möglicherweise nicht vollständig unterstützt.

💪 Vorteile

Auf der positiven Seite ist hohe Leistung ein wesentlicher Vorteil, was sie besonders geeignet für Szenarien mit intensiven Lese- und Schreiboperationen macht. Außerdem bietet sie eine einfache Handhabung, wodurch der Bedarf an manueller Synchronisationsverwaltung in einer Multi-Threading-Umgebung deutlich reduziert wird.

1. Was ist der Zweck von ConcurrentMap?

2. Welche der folgenden ist eine threadsichere Implementierung von ConcurrentMap?

3. Wie stellt ConcurrentHashMap die Threadsicherheit sicher?

question mark

Was ist der Zweck von ConcurrentMap?

Select the correct answer

question mark

Welche der folgenden ist eine threadsichere Implementierung von ConcurrentMap?

Select the correct answer

question mark

Wie stellt ConcurrentHashMap die Threadsicherheit sicher?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 2. Kapitel 5

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

Suggested prompts:

What are some common use cases for ConcurrentMap in real-world applications?

Can you explain the difference between ConcurrentHashMap and ConcurrentSkipListMap?

How does ConcurrentMap ensure thread safety compared to a regular Map?

Awesome!

Completion rate improved to 3.33

bookConcurrentmap und Seine Implementierungen

Swipe um das Menü anzuzeigen

Praxisbeispiel

Eine Webanwendung verwendet ConcurrentMap, um häufig angeforderte Daten wie Benutzersitzungen zwischenzuspeichern. Verschiedene Threads können gleichzeitig Daten aktualisieren und lesen, was schnellen Zugriff und sichere Operationen gewährleistet.

Unterschiede zu anderen Typen

  • Sicherheit in einer Multi-Thread-Umgebung: ConcurrentMap übernimmt die Synchronisierung der Datenzugriffe automatisch, während diese Aufgabe bei einer herkömmlichen Map manuell erfolgen muss;
  • Effizienz: Ermöglicht das parallele Lesen und Schreiben von Daten, ohne die gesamte Datenstruktur zu sperren.

ConcurrentMap-Implementierungen

ConcurrentHashMap: Unterstützt effizient mehrere Threads, indem die Map in Segmente (Buckets) unterteilt wird. Dadurch können Operationen parallel ausgeführt werden, ohne die gesamte Map zu sperren.

Syntax

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<>();

ConcurrentHashMap in Java unterteilt Daten in mehrere Buckets, von denen jeder durch einen eigenen Monitor verwaltet wird. Diese Struktur ermöglicht es verschiedenen Threads, Daten aus unterschiedlichen Buckets gleichzeitig zu lesen oder zu verändern, was die Leistung verbessert.

Threads können parallel auf Buckets zugreifen, wodurch Sperren reduziert und Datenrennen vermieden werden.

Jeder Bucket enthält Datensätze in Form von Schlüssel-Wert-Paaren, die als verkettete Listen organisiert sein können.

ConcurrentSkipListMap: Eine auf Skip-List basierende Implementierung, die eine sortierte Schlüsselreihenfolge unterstützt. Bietet schnelle Einfügung, Löschung und Datenzugriff in einer Multithread-Umgebung.

Syntax

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentSkipListMap = new ConcurrentSkipListMap<>();

📝Einfügen: Wenn ein neues Element zu ConcurrentSkipListMap hinzugefügt wird, beginnt es auf der untersten Ebene. Anschließend steigt es durch die Ebenen auf, bis es dort platziert ist, wo seine Schlüssel und Werte in der richtigen Reihenfolge sind.

🔍Suche: Um ein Element anhand des Schlüssels zu finden, beginnt ConcurrentSkipListMap am Kopfknoten der obersten Ebene. Es folgt den Zeigern, bis es einen Knoten mit einem Schlüssel findet, der gleich oder größer als der Suchschlüssel ist.

❌Löschen: Um ein Element aus der ConcurrentSkipListMap zu entfernen, wird es zunächst aus der untersten Ebene entfernt. Anschließend wird es durch die Ebenen nach unten verschoben, bis es aus der Position entfernt ist, an der seine Schlüssel und Werte korrekt angeordnet sind.

Beispiel für die Verwendung von ConcurrentMap im Code

Hauptmethoden

putIfAbsent(K key, V value): Fügt ein Schlüssel-Wert-Paar zur Map hinzu, nur wenn der Schlüssel noch nicht vorhanden ist.

Main.java

Main.java

copy
123
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.putIfAbsent("a", 1); // Adds the pair ("a", 1) to the map, as "a" is not already present map.putIfAbsent("a", 2); // Does not change the value, as "a" is already present in the map

remove(Object key, Object value): Entfernt das Schlüssel-Wert-Paar, wenn der Schlüssel dem angegebenen Wert zugeordnet ist.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.remove("a", 1); // Removes the pair ("a", 1), as "a" is mapped to value 1 map.remove("a", 2); // Does nothing, as "a" is not mapped to value 2

replace(K key, V value): Ersetzt den Eintrag für einen Schlüssel nur, wenn diesem aktuell ein Wert zugeordnet ist.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.replace("a", 2); // Replaces the value 1 with 2 for key "a" map.replace("b", 3); // Does nothing, as "b" is not present

compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction): Berechnet einen neuen Wert für den angegebenen Schlüssel mithilfe der bereitgestellten Remapping-Funktion, was das Erstellen eines neuen Werts, das Ändern oder das Entfernen des bestehenden Werts umfassen kann.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.compute("a", (k, v) -> v == null ? 1 : v + 1); // Increases the value for key "a" by 1 map.compute("b", (k, v) -> v == null ? 1 : v + 1); // Sets the value to 1 for new key "b"

merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction): Führt den angegebenen Wert mit dem vorhandenen Wert zusammen, der dem Schlüssel zugeordnet ist, indem die bereitgestellte Remapping-Funktion verwendet wird, die bei der Datenaggregation unterstützt.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.merge("a", 2, Integer::sum); // Sums the current value (1) with the new value (2), resulting in 3 map.merge("b", 2, Integer::sum); // Sets the value to 2 for new key "b"

getOrDefault(Object key, V defaultValue) – gibt den Wert zurück, der dem angegebenen Schlüssel zugeordnet ist, oder den Standardwert, falls der Schlüssel nicht vorhanden ist.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); int value1 = map.getOrDefault("a", 0); // Returns 1, as "a" is present int value2 = map.getOrDefault("b", 0); // Returns 0, as "b" is not present

😔 Einschränkungen

Ein potenzieller Nachteil ist die Instabilität der Reihenfolge, da einige Implementierungen während der Iteration keine Reihenfolge der Elemente garantieren. Zusätzlich kann es eine eingeschränkte Unterstützung für bestimmte Operationen geben; beispielsweise werden atomare bedingte Aktualisierungen in einigen Implementierungen möglicherweise nicht vollständig unterstützt.

💪 Vorteile

Auf der positiven Seite ist hohe Leistung ein wesentlicher Vorteil, was sie besonders geeignet für Szenarien mit intensiven Lese- und Schreiboperationen macht. Außerdem bietet sie eine einfache Handhabung, wodurch der Bedarf an manueller Synchronisationsverwaltung in einer Multi-Threading-Umgebung deutlich reduziert wird.

1. Was ist der Zweck von ConcurrentMap?

2. Welche der folgenden ist eine threadsichere Implementierung von ConcurrentMap?

3. Wie stellt ConcurrentHashMap die Threadsicherheit sicher?

question mark

Was ist der Zweck von ConcurrentMap?

Select the correct answer

question mark

Welche der folgenden ist eine threadsichere Implementierung von ConcurrentMap?

Select the correct answer

question mark

Wie stellt ConcurrentHashMap die Threadsicherheit sicher?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 2. Kapitel 5
some-alt