English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
В этом руководстве мы будем изучать примеры Java ConcurrentHashMap класса и его операций.
Класс ConcurrentHashMap из Java Collection Framework предоставляет безопасную для многопоточности карту. То есть, несколько потоков могут одновременно访问 эту карту, не влияя на一致性 элементов карты.
Он наследуетИнтерфейс ConcurrentMap.
Для создания параллельного хэш-мапа нам нужно сначала импортировать пакет java.util.concurrent.ConcurrentHashMap. После импорта пакета, мы можем создавать параллельные хэш-мапы в Java.
// ConcurrentHashMap с объемом 8 и фактором загрузки 0.6 ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);
В上面的 коде мы создали конCURRENTНУЮ хэш-карту под названием numbers.
здесь,
Key - уникальный идентификатор, используемый для связи каждого элемента (значения) в карте
Value - элемент, связанный с ключом в карте
Обратите внимание на фразу new ConcurrentHashMap<>(8, 0.6). В этом случае, первым параметром являетсяcapacity, вторым параметром являетсяloadFactor.
capacity - Объем этого маппинга составляет 8. Это означает, что он может хранить 8 элементов.
loadFactor- Фактор загрузки этой карты равен 0.6. Это означает, что как только наш хэш-таблица заполнена на 60%, элементы будут перемещены в новую хэш-таблицу, размер которой в два раза больше исходной.
Default volume and load factor
Не нужно определять его объем и фактор загрузки, чтобы создать конCURRENTНУЮ хэш-карту. Например:
// ConcurrentHashMap сdefault объемом и фактором загрузки ConcurrentHashMap<Key, Value> numbers1 = new ConcurrentHashMap<>();
По умолчанию
Объем карты будет 16
Фактор загрузки будет 0.75
Вот как мы создаем конCURRENTНУЮ хэш-карту, содержащую все элементы другого маппинга.
import java.util.concurrent.ConcurrentHashMap; import java.util.HashMap; class Main { public static void main(String[] args) { // Создание хэш-карты для четных чисел HashMap<String, Integer> evenNumbers = new HashMap<>(); evenNumbers.put("Two", 2) evenNumbers.put("Four", 4) System.out.println("HashMap: " + evenNumbers); // Создание конCURRENTНОЙ hash-карты из другого маппинга 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 предоставляет методы, которые позволяют нам выполнять различные операции над маппингом.
put() - вставляет указанное значение в map
putAll() - вставляет все элементы из указанного mappings в этот map
putIfAbsent() - вставляет указанное значение в map, если ключ уже существует
например,
import java.util.concurrent.ConcurrentHashMap; class Main { public static void main(String[] args) { //Создание ConcurrentHashMap четных чисел ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>() // использование put() evenNumbers.put("Two", 2) evenNumbers.put("Four", 4) // использование putIfAbsent() evenNumbers.putIfAbsent("Six", 6) System.out.println("КонcurrentHashMap с четными числами: " + evenNumbers) //Создание ConcurrentHashMap чисел ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(); numbers.put("One", 1); // использование putAll() numbers.putAll(evenNumbers) System.out.println("Числа в ConcurrentHashMap: " + numbers) } }
результат вывода
КонcurrentHashMap с четными числами: {Six=6, Four=4, Two=2} Числа в ConcurrentHashMap: {Six=6, One=1, Four=-4, Two=2}
1. Использование entrySet(), keySet() и values()
entrySet() - возвращает коллекцию всех ключ/значение мappings
keySet() - возвращает коллекцию всех ключей map
values() - возвращает коллекцию всех значений map
например,
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); // 使用 entrySet() System.out.println("Key/Value 映射: " + numbers.entrySet()) // 使用 keySet() System.out.println("Keys: " + numbers.keySet()) // 使用 values() System.out.println("Значения: " + numbers.values()); } }
результат вывода
ConcurrentHashMap: {One=1, Two=2, Three=3} Ключ/Значение карты: [One=1, Two=2, Three=3] Ключи: [One, Two, Three] Значения: [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); // Использование get() int value1 = numbers.get("Three"); System.out.println("Использование get(): " + value1); // Использование getOrDefault() int value2 = numbers.getOrDefault("Five", 5); System.out.println("Использование getOrDefault(): " + value2); } }
результат вывода
ConcurrentHashMap: {One=1, Two=2, Three=3} Использование get(): 3 Использование getOrDefault(): 5
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); // Метод удаления с одним параметром int value = numbers.remove("Two"); System.out.println("Удаленное значение: " + value); // Метод удаления с двумя параметрами boolean result = numbers.remove("Three", 3); System.out.println("Элемент {Three=3} был удален? " + result); System.out.println("Обновленный ConcurrentHashMap: " + numbers); } }
результат вывода
ConcurrentHashMap: {One=1, Two=2, Three=3} Удаленное значение: 2 Элемент {Three=3} был удален? True Обновленный ConcurrentHashMap: {One=1}
Класс ConcurrentHashMap предоставляет безопасные методы для параллельных batch-операций с различными map.
1. Метод forEach()
она содержит два параметра.
Метод forEach()遍历 наши записи и выполняет指定的 функцию.
parallelismThreshold - это параметр, который specifies, после скольких элементов в мапе выполняется операция параллельно.
например,
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); transformer - это функция, которая преобразует данные перед передачей их в指定的 функцию. //forEach() не содержит переданной функции // forEach() передается指定的 функция System.out.print("Значения: "); numbers.forEach(4, (k, v) -> v, (v) -> System.out.print(v + ", ")); } }
результат вывода
ConcurrentHashMap: {One = 1, Two = 2, Three = 3} ключ: One значение: 1 ключ: Two значение: 2 ключ: Three значение: 3 Значения: 1, 2, 3,
В上面的 программе мы использовали параметр параллельного порога4Это означает, что если в мапе содержится 4 записи, то операция выполняется параллельно.
варианты метода forEach()
forEachEntry() - выполняет指定的 функцию для каждой записи
forEachKey() - выполняет指定的 функцию для каждого ключа
forEachValue() - выполняет指定的 функцию для каждого значения
Метод search() ищет map по指定的 функции и возвращает соответствующие записи.
Здесь,指定的 функция определяет, что искать.
Он также содержит опциональный параметр parallelThreshold. Параметр параллельного порога specifies, после скольких элементов в мапе выполняется операция параллельно.
например,
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("Поисковое значение: " + key); } }
результат вывода
ConcurrentHashMap: {One=1, Two=2, Three=3} Поисковое значение: Three
варианты метода search()
searchEntries() - поисковая функция применяется к ключ/значению
searchKeys() - поисковая функция применяется только к ключам
searchValues() - поисковая функция применяется только к значениям
метод reduce() накопляет (агрегирует) каждую запись в мапе. Когда нам нужны все записи для выполнения задачи (например, суммирование всех значений мапы), мы можем использовать этот метод.
она содержит два параметра.
parallelismThreshold - это параметр, который указывает, после скольких элементов операции в мапе будут выполняться параллельно.
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() - возвращение результата сбора всех записей с использованием指定的 функции редуктора
reduceKeys() - возвращение результата сбора всех ключей с использованием指定的 функции редуктора
reduceValues() - возвращение результата сбора всех значений с использованием指定的 функции редуктора
Ниже приведены различия между ConcurrentHashMap иHashMap之间存在一些区别
ConcurrentHashMap являетсяТред-безопасностьСборники. То есть, несколько потоков могут одновременно доступ к ним и их модификация.
ConcurrentHashMap предоставляет методы для параллельных операций, таких как forEach(), search() и reduce().
Класс ConcurrentHashMap позволяет множеству потоков выполнять параллельные операции по модификации.
По умолчанию, параллельные хэш-маппинги разделены16段Вот почему разрешается одновременное изменение карты 16 потоками. Но в один момент может быть доступно любое количество потоков.
Если指定的 ключ уже существует, то метод putIfAbsent() не будет заменять запись в маппинге.