English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Java Grund教程

Java 流程控制

Java 数组

Java 面向对象(I)

Java 面向对象(II)

Java 面向对象(III)

Java Ausnahmebehandlung

Java 列表(List)

Java Queue(队列)

Java Map集合

Java Set集合

Java 输入输出(I)/O)

Java Reader/Writer

Java 其他主题

Java ConcurrentHashMap

在本教程中,我们将借助示例学习Java ConcurrentHashMap类及其操作。

Java集合框架的ConcurrentHashMap类提供了线程安全的映射。也就是说,多个线程可以一次访问该映射,而不会影响映射中条目的一致性。

它继承了ConcurrentMap接口

创建一个ConcurrentHashMap

为了创建并发的哈希图,我们必须先导入java.util.concurrent.ConcurrentHashMap包。导入包后,就可以在Java中创建并发哈希映射。

//ConcurrentHashMap具有容量8和负载因子0.6
ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);

在上面的代码中,我们创建了一个名为numbers的并发哈希映射。

这里,

  • Schlüssel - 用于关联map中每个元素(值)的唯一标识符

  • Value - map中与键相关联的元素

注意语句 new ConcurrentHashMap<>(8, 0.6)。在这里,第一个参数是capacity,第二个参数是loadFactor

  • capacity -该映射的容量为8。意味着,它可以存储8个条目。

  • loadFactor-此map的负载因子为0.6。这意味着,只要我们的哈希表填充了60%,条目就会移到新哈希表中,其大小是原始哈希表的两倍。

默认容量和负载因子

无需定义其容量和负载因子就可以创建并发哈希图。例如,

// 具有默认容量和负载因子的ConcurrentHashMap
ConcurrentHashMap<Key, Value> numbers1 = new ConcurrentHashMap<>();

Standardmäßig,

  • Die Kapazität der Map wird 16

  • Der Ladefaktor wird 0 sein.75

Erstellung von ConcurrentHashMap aus anderen Mappings

Dies ist unsere Methode, um einen concurrenten Hashmap zu erstellen, der alle Elemente anderer Mappings enthält.

import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
class Main {
    public static void main(String[] args) {
        // Erstellung der geraden HashMap
        HashMap<String, Integer> evenNumbers = new HashMap<>();
        evenNumbers.put("Two", 2);
        evenNumbers.put("Four", 4);
        System.out.println("HashMap: ", + evenNumbers);
        //Erstellung eines concurrenten Hashmaps aus anderen Mappings
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(evenNumbers);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);
    }
}

输出结果

HashMap: {Four=4, Two=2}
ConcurrentHashMap: {Four=4, Two=2, Three=3}

Methoden der ConcurrentHashMap

Die Klasse ConcurrentHashMap bietet Methoden, die es uns erlauben, verschiedene Operationen auf dem Mapping auszuführen.

Fügt den Element in die ConcurrentHashMap ein

  • put() - Fügt den angegebenen Schlüssel hinzu/Wertzuordnung wird in das Mapping eingefügt

  • putAll() - Fügt alle Einträge des angegebenen Mappings in dieses Map ein

  • putIfAbsent() - Fügt den angegebenen Schlüssel hinzu, falls der Schlüssel im Mapping nicht existiert/Wertzuordnung wird in das Map eingefügt

例如,

import java.util.concurrent.ConcurrentHashMap;
class Main {
    public static void main(String[] args) {
        //Erstellung der geraden ConcurrentHashMap
        ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>();
        // Verwendung von put()
        evenNumbers.put("Two", 2);
        evenNumbers.put("Four", 4);
        // Verwendung von putIfAbsent()
        evenNumbers.putIfAbsent("Six", 6);
        System.out.println("Die geraden ConcurrentHashMap: ", + evenNumbers);
        //Erstellung der ConcurrentHashMap numbers
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        // Verwendung von putAll()
        numbers.putAll(evenNumbers);
        System.out.println("Die geraden ConcurrentHashMap-Zahlen: ", + numbers);
    }
}

输出结果

Eingabe der geraden ConcurrentHashMap: {Six=6, One=4, Two=2}
ConcurrentHashMap的数字为: {Six=6ConcurrentHashMap-Zahlen: {Six=1, One=-4, Two=2}

, Four=

1Zugriff auf ConcurrentHashMap-Elemente

  • .Verwenden Sie entrySet(), keySet() und values() - entrySet()/Gibt eine Sammlung aller Schlüssel zurück

  • Wert-Mapping-Sammlung - keySet()

  • Gibt die Sammlung aller Schlüssel im Map zurück - values()

例如,

import java.util.concurrent.ConcurrentHashMap;
class Main {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);
        // Gibt die Sammlung aller Werte im Map zurück
        Verwenden Sie entrySet()/Wert-Mapping: " + numbers.entrySet());
        // Verwenden Sie keySet()
        System.out.println("Schlüssel: ") + numbers.keySet());
        // Verwenden Sie values()
        System.out.println("Werte: ") + numbers.values());
    }
}

输出结果

ConcurrentHashMap: {One=1, Two=2, Three=3}
Schlüssel/Wert-Mapping: [One=1, Two=2, Three=3]
Schlüssel: [One, Two, Three]
Werte: [1, 2, 3]

2.Verwenden Sie get() und getOrDefault()

  • get() - Gibt den mit dem angegebenen Schlüssel verknüpften Wert zurück. Wenn der Schlüssel nicht gefunden wird, wird null zurückgegeben.

  • getOrDefault() - Gibt den mit dem angegebenen Schlüssel verknüpften Wert zurück. Wenn der Schlüssel nicht gefunden wird, wird der angegebene Standardwert zurückgegeben.

例如,

import java.util.concurrent.ConcurrentHashMap;
class Main {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);
        // Verwenden Sie get()
        int value1 = numbers.get("Three");
        System.out.println("Verwenden Sie get(): " + value1);
        // Verwenden Sie getOrDefault()
        int value2 = numbers.getOrDefault("Five", 5);
        System.out.println("Verwenden Sie getOrDefault(): " + value2);
    }
}

输出结果

ConcurrentHashMap: {One=1, Two=2, Three=3}
Verwenden Sie get(): 3
Verwenden Sie getOrDefault(): 5

ConcurrentHashMap-Elemente löschen

  • remove(key) - Gibt den mit dem angegebenen Schlüssel verknüpften Eintrag zurück und entfernt ihn aus dem Mapping

  • remove(key, value) - Eintrag wird nur aus dem Mapping entfernt, wenn der angegebene Schlüssel den angegebenen Wert hat und der Rückgabewert boolean ist

例如,

import java.util.concurrent.ConcurrentHashMap;
class Main {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);
        //Einzelnes Entfernen
        int value = numbers.remove("Two");
        System.out.println("Gelöschter Wert: " + value);
        // Methode mit zwei Parametern
        boolean result = numbers.remove("Three", 3);
        System.out.println("Eintrag {Three=")}3} wurde gelöscht? " + result);
        System.out.println("Aktualisierte ConcurrentHashMap: ", + numbers);
    }
}

输出结果

ConcurrentHashMap: {One=1, Two=2, Three=3}
Gelöschter Wert: 2
Eintrag {Three=3} wurde gelöscht? True
Aktualisierte ConcurrentHashMap: {One=1}

Batch-Operationenmethoden der ConcurrentHashMap

Die ConcurrentHashMap-Klasse bietet verschiedene Batch-Operationenmethoden an, die sicher angewendet werden können.

1. forEach() Methode

Die forEach() Methode durchsucht unsere Einträge und führt die angegebene Funktion aus.

它包含两个参数。

  • parallelismThreshold -Es gibt an, wie viele Elementoperationen im Mapping nach der Parallelisierung ausgeführt werden sollen.

  • transformer -Dies wird vor der Übertragung der Daten an die angegebene Funktion die Daten umgewandelt.

例如,

import java.util.concurrent.ConcurrentHashMap;
class Main {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);
        //forEach() enthält keine übergebene Funktion
        numbers.forEach(4, (k, v) -> System.out.println("Schlüssel: ", + k + " value: " + v));
        // forEach() übergibt die angegebene Funktion
        System.out.print("Werte sind ");
        numbers.forEach(4, (k, v) -> v, (v) -> System.out.print(v + ", "));
    }
}

输出结果

ConcurrentHashMap: {One = 1, Two = 2, Three = 3}
Schlüssel: One Wert: 1
Schlüssel: Two Wert: 2
Schlüssel: Three Wert: 3
Werte sind 1, 2, 3,

In dem obigen Programm haben wir den Parallelitätsschwellenwert verwendet4. Dies bedeutet, dass, wenn das Mapping4dieser Operation parallel ausgeführt wird.

Variante der forEach() Methode

  • forEachEntry() - Führt die angegebene Funktion für jeden Eintrag aus

  • forEachKey() - Führt die angegebene Funktion für jeden Schlüssel aus

  • forEachValue() - Führt die angegebene Funktion für jeden Wert aus

2. search() Methode

Die search() Methode sucht das Map basierend auf der angegebenen Funktion und gibt den passenden Eintrag zurück.

Hier bestimmt die angegebene Funktion, welche Einträge gesucht werden.

Es enthält auch einen optionalen Parameter parallelThreshold. Der Parallelitätsschwellenwert gibt an, wie viele Elemente im Mapping nach der Parallelisierung der Operationen ausgeführt werden sollen.

例如,

import java.util.concurrent.ConcurrentHashMap;
class Main {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);
        // 使用 search()
        String key = numbers.search(4, (k, v) -> {return v == 3 ? k: null;});
        System.out.println("Der gesuchte Wert: ", + key);
    }
}

输出结果

ConcurrentHashMap: {One=1, Two=2, Three=3}
被搜索的值: Three

search()方法的变体

  • searchEntries() - 搜索函数应用于键/值映射

  • searchKeys() - 搜索函数仅适用于按键

  • searchValues() - 搜索函数仅应用于值

3. reduce()方法

reduce()方法累积(聚集)映射中的每个条目。 当我们需要所有条目来执行一项常见任务(例如添加映射的所有值)时,可以使用此方法。

它包含两个参数。

  • parallelismThreshold -它指定在有多少元素之后,map中的操作将并行执行。

  • transformer - 这将在数据传递给指定函数之前对数据进行转换。

例如,

import java.util.concurrent.ConcurrentHashMap;
class Main {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);
        // 使用 search()
        int sum = numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1 + v2);
        System.out.println("所有值的总和: " + sum);
    }
}

输出结果

ConcurrentHashMap: {One=1, Two=2, Three=3}
所有值的总和: 6

在上面的程序中,请注意以下语句

numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1+v2);

这里,

  • 4 是并行阈值

  • (k, v) -> v是一个转换函数。它将键/值映射仅转换为值。

  • (v1, v2) -> v1+v2 是计算大小函数。它收集所有值并将所有值相加。

reduce()方法的变体

  • reduceEntries() - 返回使用指定的reducer函数收集所有条目的结果

  • reduceKeys() - 返回使用指定的reducer函数收集所有键的结果

  • reduceValues() - Gibt das Ergebnis zurück, das alle Werte durch den angegebenen Reducer-Funktion sammelt

Unterschiede zwischen ConcurrentHashMap und HashMap

Hier sind ConcurrentHashMap undHashMapEinige Unterschiede zwischen

  • ConcurrentHashMap istthread-sicherKollektionen. Das bedeutet, dass mehrere Threads gleichzeitig darauf zugreifen und sie ändern können.

  • ConcurrentHashMap bietet Methoden für Batch-Operationen wie forEach(), search() und reduce().

Warum ConcurrentHashMap wählen?

  • Die ConcurrentHashMap-Klasse ermöglicht es mehreren Threads, die Modifikationsoperationen gleichzeitig durchzuführen.

  • Standardmäßig wird die concurrente Hash-Mapping in16AbschnittDas ist der Grund, warum es erlaubt ist16Warum gibt es mehrere Threads, die gleichzeitig den Mapping ändern?

  • Die putIfAbsent()-Methode wird den Eintrag im Mapping nicht überschreiben, wenn der angegebene Schlüssel bereits existiert.