Java Concurrency - ConcurrentMap-Schnittstelle

Eine java.util.concurrent.ConcurrentMap-Schnittstelle ist eine Unterschnittstelle der Map-Schnittstelle und unterstützt atomare Operationen für zugrunde liegende Map-Variablen. Es verfügt über Methoden zum Abrufen und Festlegen, die wie das Lesen und Schreiben flüchtiger Variablen funktionieren. Das heißt, eine Menge hat eine Vorher-Beziehung zu einem nachfolgenden Abruf derselben Variablen. Diese Schnittstelle gewährleistet Gewindesicherheit und Atomarität.

ConcurrentMap-Methoden

Sr.Nr. Methode & Beschreibung
1

default V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)

Versuche, eine Zuordnung für den angegebenen Schlüssel und seinen aktuellen zugeordneten Wert zu berechnen (oder null, wenn keine aktuelle Zuordnung vorhanden ist).

2

default V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)

Wenn der angegebene Schlüssel noch keinem Wert zugeordnet ist (oder null zugeordnet ist), wird versucht, seinen Wert mithilfe der angegebenen Zuordnungsfunktion zu berechnen und in diese Zuordnung einzugeben, sofern nicht null.

3

default V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)

Wenn der Wert für den angegebenen Schlüssel vorhanden und nicht null ist, wird versucht, eine neue Zuordnung unter Berücksichtigung des Schlüssels und seines aktuellen zugeordneten Werts zu berechnen.

4

default void forEach(BiConsumer<? super K,? super V> action)

Führt die angegebene Aktion für jeden Eintrag in dieser Zuordnung aus, bis alle Einträge verarbeitet wurden oder die Aktion eine Ausnahme auslöst.

5

default V getOrDefault(Object key, V defaultValue)

Gibt den Wert zurück, dem der angegebene Schlüssel zugeordnet ist, oder defaultValue, wenn diese Zuordnung keine Zuordnung für den Schlüssel enthält.

6

default V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)

Wenn der angegebene Schlüssel noch keinem Wert oder null zugeordnet ist, ordnet er ihn dem angegebenen Wert ungleich Null zu.

7

V putIfAbsent(K key, V value)

Wenn der angegebene Schlüssel noch keinem Wert zugeordnet ist, ordnen Sie ihn dem angegebenen Wert zu.

8

boolean remove(Object key, Object value)

Entfernt den Eintrag für einen Schlüssel nur, wenn er aktuell einem bestimmten Wert zugeordnet ist.

9

V replace(K key, V value)

Ersetzt den Eintrag für einen Schlüssel nur, wenn er derzeit einem bestimmten Wert zugeordnet ist.

10

boolean replace(K key, V oldValue, V newValue)

Ersetzt den Eintrag für einen Schlüssel nur, wenn er aktuell einem bestimmten Wert zugeordnet ist.

11

default void replaceAll(BiFunction<? super K,? super V,? extends V> function)

Ersetzt den Wert jedes Eintrags durch das Ergebnis des Aufrufs der angegebenen Funktion für diesen Eintrag, bis alle Einträge verarbeitet wurden oder die Funktion eine Ausnahme auslöst.

Beispiel

Das folgende TestThread-Programm zeigt die Verwendung von ConcurrentMap gegenüber HashMap.

import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class TestThread {

   public static void main(final String[] arguments) {
      Map<String,String> map = new ConcurrentHashMap<String, String>();

      map.put("1", "One");
      map.put("2", "Two");
      map.put("3", "Three");
      map.put("5", "Five");
      map.put("6", "Six");

      System.out.println("Initial ConcurrentHashMap: " + map);
      Iterator<String> iterator = map.keySet().iterator();

      try { 
         
         while(iterator.hasNext()) {
            String key = iterator.next();
            
            if(key.equals("3")) {
               map.put("4", "Four");
            }
         }
      } catch(ConcurrentModificationException cme) {
         cme.printStackTrace();
      }
      System.out.println("ConcurrentHashMap after modification: " + map);

      map = new HashMap<String, String>();

      map.put("1", "One");
      map.put("2", "Two");
      map.put("3", "Three");
      map.put("5", "Five");
      map.put("6", "Six");

      System.out.println("Initial HashMap: " + map);
      iterator = map.keySet().iterator();

      try {
         
         while(iterator.hasNext()) {
            String key = iterator.next();
            
            if(key.equals("3")) {
               map.put("4", "Four");
            }
         }
         System.out.println("HashMap after modification: " + map);
      } catch(ConcurrentModificationException cme) {
         cme.printStackTrace();
      }
   }  
}

Dies führt zu folgendem Ergebnis.

Ausgabe

Initial ConcurrentHashMap: {1 = One, 2 = Two, 3 = Three, 5 = Five, 6 = Six}
ConcurrentHashMap after modification: {1 = One, 2 = Two, 3 = Three, 4 = Four, 5 = Five, 6 = Six}
Initial HashMap: {1 = One, 2 = Two, 3 = Three, 5 = Five, 6 = Six}
java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextNode(Unknown Source)
	at java.util.HashMap$KeyIterator.next(Unknown Source)
	at TestThread.main(TestThread.java:48)