Java ConcurrentHashMap
Java ConcurrentHashMap
В этом руководстве мы узнаем о классе Java ConcurrentHashMap и его операциях с помощью примеров.
ConcurrentHashMap
класс платформы коллекций Java предоставляет поточно-ориентированную карту. То есть несколько потоков могут одновременно обращаться к карте, не влияя на согласованность записей в карте.
Он реализует интерфейс ConcurrentMap.
<час>
Создать ConcurrentHashMap
Чтобы создать параллельную хэш-карту, мы должны импортировать java.util.concurrent.ConcurrentHashMap
пакет первый. Как только мы импортируем пакет, вот как мы можем создавать параллельные хэш-карты в Java.
// ConcurrentHashMap with capacity 8 and load factor 0.6
ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);
В приведенном выше коде мы создали параллельную хэш-карту с именем numbers. .
Здесь
- Ключ - уникальный идентификатор, используемый для связывания каждого элемента (значения) на карте
- Значение - элементы, связанные ключами на карте
Обратите внимание на часть new ConcurrentHashMap<>(8, 0.6)
. Здесь первым параметром является вместимость. а второй параметр — коэффициент нагрузки. .
- вместимость - Емкость этой карты 8. Это означает, что она может хранить 8 записей.
- коэффициент нагрузки - Коэффициент загрузки этой карты 0,6. Это означает, что всякий раз, когда наша хеш-таблица заполняется на 60 %, записи перемещаются в новую хэш-таблицу, размер которой вдвое превышает размер исходной хеш-таблицы.
Емкость и коэффициент загрузки по умолчанию
Можно создать параллельную хэш-карту без определения ее емкости и коэффициента загрузки. Например,
// ConcurrentHashMap with default capacity and load factor
ConcurrentHashMap<Key, Value> numbers1 = new ConcurrentHashMap<>();
По умолчанию
- вместимость карты будет 16
- коэффициент загрузки будет 0,75
Создание ConcurrentHashMap из других карт
Вот как мы можем создать параллельную хэш-карту, содержащую все элементы других карт.
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
class Main {
public static void main(String[] args) {
// Creating a hashmap of even numbers
HashMap<String, Integer> evenNumbers = new HashMap<>();
evenNumbers.put("Two", 2);
evenNumbers.put("Four", 4);
System.out.println("HashMap: " + evenNumbers);
// Creating a concurrent hashmap from other map
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}<час>
Методы ConcurrentHashMap
ConcurrentHashMap
класс предоставляет методы, которые позволяют нам выполнять различные операции на карте.
Вставить элементы в ConcurrentHashMap
put()
- вставляет указанное сопоставление ключа/значения в картуputAll()
- вставляет все записи из указанной карты в эту картуputIfAbsent()
- вставляет указанное сопоставление ключа/значения в карту, если указанный ключ отсутствует в карте
Например,
import java.util.concurrent.ConcurrentHashMap;
class Main {
public static void main(String[] args) {
// Creating ConcurrentHashMap of even numbers
ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>();
// Using put()
evenNumbers.put("Two", 2);
evenNumbers.put("Four", 4);
// Using putIfAbsent()
evenNumbers.putIfAbsent("Six", 6);
System.out.println("ConcurrentHashMap of even numbers: " + evenNumbers);
//Creating ConcurrentHashMap of numbers
ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
numbers.put("One", 1);
// Using putAll()
numbers.putAll(evenNumbers);
System.out.println("ConcurrentHashMap of numbers: " + numbers);
}
}
Вывод
ConcurrentHashMap of even numbers: {Six=6, Four=4, Two=2} ConcurrentHashMap of numbers: {Six=6, One=1, Four=-4, Two=2}<час>
Доступ к элементам ConcurrentHashMap
<сильный>1. Использование entrySet(), keySet() и values()
entrySet()
- возвращает набор всех сопоставлений ключ/значение картыkeySet()
- возвращает набор всех ключей карты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);
// Using entrySet()
System.out.println("Key/Value mappings: " + numbers.entrySet());
// Using keySet()
System.out.println("Keys: " + numbers.keySet());
// Using values()
System.out.println("Values: " + numbers.values());
}
}
Вывод
ConcurrentHashMap: {One=1, Two=2, Three=3} Key/Value mappings: [One=1, Two=2, Three=3] Keys: [One, Two, Three] Values: [1, 2, 3]
<сильный>2. Использование get() и getOrDefault()
get()
- Возвращает значение, связанное с указанным ключом. Возвращаетnull
если ключ не найден.getOrDefault()
- Возвращает значение, связанное с указанным ключом. Возвращает указанное значение по умолчанию, если ключ не найден.
Например,
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);
// Using get()
int value1 = numbers.get("Three");
System.out.println("Using get(): " + value1);
// Using getOrDefault()
int value2 = numbers.getOrDefault("Five", 5);
System.out.println("Using getOrDefault(): " + value2);
}
}
Вывод
ConcurrentHashMap: {One=1, Two=2, Three=3} Using get(): 3 Using getOrDefault(): 5<час>
Удалить элементы ConcurrentHashMap
remove(key)
- возвращает и удаляет запись, связанную с указанным ключом, с картыremove(key, value)
- удаляет запись с карты, только если указанный ключ сопоставлен с указанным значением и возвращает логическое значение
Например,
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);
// remove method with single parameter
int value = numbers.remove("Two");
System.out.println("Removed value: " + value);
// remove method with two parameters
boolean result = numbers.remove("Three", 3);
System.out.println("Is the entry {Three=3} removed? " + result);
System.out.println("Updated ConcurrentHashMap: " + numbers);
}
}
Вывод
ConcurrentHashMap: {One=1, Two=2, Three=3} Removed value: 2 Is the entry {Three=3} removed? True Updated ConcurrentHashMap: {One=1}<час>
Массовые операции ConcurrentHashMap
ConcurrentHashMap
класс предоставляет различные массовые операции, которые можно безопасно применять к параллельным картам.
1. Метод forEach()
forEach()
метод перебирает наши записи и выполняет указанную функцию.
Он включает два параметра.
- Порог параллелизма - Указывает, через какое количество элементов операции на карте выполняются параллельно.
- трансформер – Это преобразует данные до того, как данные будут переданы в указанную функцию.
Например,
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() without transformer function
numbers.forEach(4, (k, v) -> System.out.println("key: " + k + " value: " + v));
// forEach() with transformer function
System.out.print("Values are ");
numbers.forEach(4, (k, v) -> v, (v) -> System.out.print(v + ", "));
}
}
Вывод
ConcurrentHashMap: {One = 1, Two = 2, Three = 3} key: One value: 1 key: Two value: 2 key: Three value: 3 Values are 1, 2, 3,
В приведенной выше программе мы использовали параллельный порог 4. . Это означает, что если карта содержит 4 записи, операция будет выполняться параллельно.
Вариант метода forEach()
forEachEntry()
- выполняет указанную функцию для каждой записиforEachKey()
- выполняет указанную функцию для каждой клавишиforEachValue()
- выполняет указанную функцию для каждого значения
2. Метод поиска()
search()
метод ищет карту на основе указанной функции и возвращает совпадающую запись.
Здесь указанная функция определяет, какую запись следует искать.
Он также включает необязательный параметр parallelThreshold. . Порог параллелизма указывает, после какого количества элементов на карте операция выполняется параллельно.
Например,
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);
// Using search()
String key = numbers.search(4, (k, v) -> {return v == 3 ? k: null;});
System.out.println("Searched value: " + key);
}
}
Вывод
ConcurrentHashMap: {One=1, Two=2, Three=3} Searched value: Three
Варианты метода search()
searchEntries()
- функция поиска применяется к сопоставлениям ключ/значениеsearchKeys()
- функция поиска применяется только к ключамsearchValues()
- функция поиска применяется только к значениям
3. Метод уменьшения()
reduce()
метод накапливает (собирает вместе) каждую запись на карте. Это можно использовать, когда нам нужны все записи для выполнения общей задачи, например добавления всех значений карты.
Он включает два параметра.
- Порог параллелизма – Указывает, после скольких элементов операции на карте выполняются параллельно.
- трансформер – Это преобразует данные до того, как данные будут переданы в указанную функцию.
Например,
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);
// Using search()
int sum = numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1 + v2);
System.out.println("Sum of all values: " + sum);
}
}
Вывод
ConcurrentHashMap: {One=1, Two=2, Three=3} Sum of all values: 6
В приведенной выше программе обратите внимание на оператор
numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1+v2);
Здесь
- 4 – параллельный порог.
- (k, v) -> v является функцией преобразователя. Он преобразует сопоставления "ключ-значение" только в значения.
- (v1, v2) -> v1+v2 является редукционной функцией. Он собирает все значения и добавляет все значения.
Варианты метода reduce()
reduceEntries()
- возвращает результат сбора всех записей с помощью указанной функции редуктораreduceKeys()
- возвращает результат сбора всех ключей с помощью указанной функции редуктораreduceValues()
- возвращает результат сбора всех значений с помощью указанной функции редуктора
ConcurrentHashMap и HashMap
Вот некоторые различия между ConcurrentHashMap
и HashMap,
ConcurrentHashMap
является поточно-ориентированным коллекция. То есть несколько потоков могут одновременно обращаться к нему и изменять его.ConcurrentHashMap
предоставляет методы для массовых операций, таких какforEach()
,search()
иreduce()
.
Почему ConcurrentHashMap?
ConcurrentHashMap
class позволяет нескольким потокам одновременно обращаться к своим записям.- По умолчанию параллельная хеш-карта разделена на 16 сегментов. . По этой причине 16 потокам разрешено одновременно изменять карту. Однако одновременно к карте может обращаться любое количество потоков.
putIfAbsent()
метод не переопределит запись в карте, если указанный ключ уже существует.- Он обеспечивает собственную синхронизацию.
java