English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
在本教程中,我们将借助示例学习Java ConcurrentHashMap类及其操作。
Java集合框架的ConcurrentHashMap类提供了线程安全的映射。也就是说,多个线程可以一次访问该映射,而不会影响映射中条目的一致性。
它继承了ConcurrentMap接口。
为了创建并发的哈希图,我们必须先导入java.util.concurrent.ConcurrentHashMap包。导入包后,就可以在Java中创建并发哈希映射。
//ConcurrentHashMap具有容量8和负载因子0.6 ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);
在上面的代码中,我们创建了一个名为numbers的并发哈希映射。
aquí,
Clave - 用于关联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<>();
Por defecto,
La capacidad del map será 16
El factor de carga será 0.75
Así es como creamos un ConcurrentHashMap que contiene todos los elementos de otro mapeo.
import java.util.concurrent.ConcurrentHashMap; import java.util.HashMap; class Main { public static void main(String[] args) { // Crear HashMap par HashMap<String, Integer> evenNumbers = new HashMap<>(); evenNumbers.put("Two", 2); evenNumbers.put("Four", 4); System.out.println("HashMap: ", + evenNumbers); //Crear ConcurrentHashMap desde otro mapeo ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(evenNumbers); numbers.put("Three", 3); System.out.println("ConcurrentHashMap: " + numbers); } }
Resultados de salida
HashMap: {Four=4, Two=2} ConcurrentHashMap: {Four=4, Two=2, Three=3}
La clase ConcurrentHashMap proporciona métodos que nos permiten realizar varias operaciones en el mapeo.
put() - Insertar la clave especificada/Insertar valores mapeados en el mapeo
putAll() - Insertar todos los elementos del mapeo especificado en este map
putIfAbsent() - Si el mapeo no contiene la clave especificada, insertar la clave especificada/Insertar valores mapeados en el map
por ejemplo,
import java.util.concurrent.ConcurrentHashMap; class Main { public static void main(String[] args) { //Creando ConcurrentHashMap par ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>(); // Usando put() evenNumbers.put("Two", 2); evenNumbers.put("Four", 4); // Usando putIfAbsent() evenNumbers.putIfAbsent("Six", 6); System.out.println("El ConcurrentHashMap par: ", + evenNumbers); //Creando ConcurrentHashMap de números ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(); numbers.put("One", 1); // Usando putAll() numbers.putAll(evenNumbers); System.out.println("El ConcurrentHashMap de números: ", + numbers); } }
Resultados de salida
El ConcurrentHashMap par: {Six=6, Four=4, Two=2} ConcurrentHashMap de números: {Six=6, One=1, Four=-4, Two=2}
1.usando entrySet(), keySet() y values()
entrySet() - devuelve un conjunto de todas las claves/colección del mapeo de valores
keySet() - devuelve la colección de todas las claves del mapa
values() - devuelve la colección de todos los valores del mapa
por ejemplo,
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); // usando entrySet() System.out.println("Clave/Mapa de valores: + numbers.entrySet()); // usando keySet() System.out.println("Claves: ") + numbers.keySet()); // usando values() System.out.println("Valores: ") + numbers.values()); } }
Resultados de salida
ConcurrentHashMap: {One=1, Two=2, Three=3} Clave/Mapa de valores: [One=1, Two=2, Three=3] Claves: [One, Two, Three] Valores: [1, 2, 3]
2.usando get() y getOrDefault()
get() - devuelve el valor asociado con la clave especificada. Si no se encuentra la clave, devuelve null.
getOrDefault() - devuelve el valor asociado con la clave especificada. Si no se encuentra la clave, devuelve el valor de predeterminado especificado.
por ejemplo,
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); // usando get() int value1 = numbers.get("Three"); System.out.println("usando get(): " + value1); // usando getOrDefault() int value2 = numbers.getOrDefault("Five", 5); System.out.println("usando getOrDefault(): " + value2); } }
Resultados de salida
ConcurrentHashMap: {One=1, Two=2, Three=3} usando get(): 3 usando getOrDefault(): 5
remove(key) - devuelve y elimina la entrada asociada con la clave especificada de la tabla de mapeo
remove(key, value) - sólo se elimina la entrada de la tabla de mapeo cuando la clave está mapeada al valor especificado y se devuelve un valor booleano
por ejemplo,
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); //método de eliminación con un solo parámetro int value = numbers.remove("Two"); System.out.println("Valor eliminado: " + value); // método de eliminación con dos parámetros boolean result = numbers.remove("Three", 3); System.out.println("Entrada {Three=3} ¿Fue eliminado? " + result); System.out.println("ConcurrentHashMap actualizado: ", + numbers); } }
Resultados de salida
ConcurrentHashMap: {One=1, Two=2, Three=3} Valor eliminado: 2 Entrada {Three=3} ¿Fue eliminado? True ConcurrentHashMap actualizado: {One=1}
La clase ConcurrentHashMap proporciona métodos de batch operativos que se pueden aplicar de manera segura a diferentes mapas paralelos.
El método forEach() recorre nuestras entradas y ejecuta la función especificada.
contiene dos parámetros.
parallelismThreshold -Especifica cuántos elementos de la operación se ejecutarán en paralelo en el mapeo.
transformer -Esto convertirá los datos antes de pasarlos a la función especificada.
por ejemplo,
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() no contiene la función transmitida numbers.forEach(4, (k, v) -> System.out.println("clave: ", + k + " valor: " + v)); // forEach() pasa la función especificada System.out.print("Los valores son "); numbers.forEach(4, (k, v) -> v, (v) -> System.out.print(v + , "); } }
Resultados de salida
ConcurrentHashMap: {One = 1, Two = 2, Three = 3} clave: One valor: 1 clave: Two valor: 2 clave: Three valor: 3 Los valores son 1, 2, 3,
En el programa anterior, utilizamos el umbral de paralelismo4. Esto significa que, si el map contiene4operación se ejecutará en paralelo.
Variantes del método forEach()
forEachEntry() - Ejecuta la función especificada para cada entrada
forEachKey() - Ejecuta la función especificada para cada clave
forEachValue() - Ejecuta la función especificada para cada valor
El método search() busca en el map basado en la función especificada y devuelve la entrada coincidente.
Aquí, la función especificada determina qué entrada buscar.
Además, contiene un parámetro opcional parallelThreshold. El umbral de paralelismo especifica cuántos elementos en el mapeo deben existir antes de ejecutar la operación en paralelo.
por ejemplo,
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); // usando search() String key = numbers.search(4, (k, v) -> {return v == 3 ? k: null;}); System.out.println("Valor buscado: ", + key); } }
Resultados de salida
ConcurrentHashMap: {One=1, Two=2, Three=3} valor a buscar: Three
variante del método search()
searchEntries() - la función de búsqueda se aplica a las claves/mapeo de valores
searchKeys() - la función de búsqueda se aplica solo a las claves
searchValues() - la función de búsqueda se aplica solo a los valores
El método reduce() acumula (agrega) cada entrada en el mapeo. Cuando necesitemos todos los elementos para ejecutar una tarea común (por ejemplo, agregar todos los valores del mapeo), podemos usar este método.
contiene dos parámetros.
parallelismThreshold -especifica cuántos elementos después, la operación en el map se ejecutará en paralelo.
transformer - esto convertirá los datos antes de que se pasen al función especificada
por ejemplo,
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); // usando search() int sum = numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1 + v2); System.out.println("La suma total de todos los valores: " + sum); } }
Resultados de salida
ConcurrentHashMap: {One=1, Two=2, Three=3} La suma total de todos los valores: 6
En el programa anterior, preste atención a las siguientes instrucciones
numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1+v2);
aquí,
4 es el umbral paralelo
(k, v) -> v es una función de conversión. Transforma las claves/la mapeo de valores se convierte solo en valores.
(v1, v2) -> v1+v2 es una función de cálculo de tamaño. Recolecta todos los valores y los suma.
variante del método reduce()
reduceEntries() - devuelve el resultado de recopilar todos los elementos utilizando la función reducer especificada
reduceKeys() - devuelve el resultado de recopilar todos los valores utilizando la función reducer especificada
reduceValues() - devuelve el resultado de recopilar todos los valores utilizando la función reductora especificada
A continuación se muestra la diferencia entre ConcurrentHashMap yHashMapdiferencias entre
ConcurrentHashMap es线程安全的conjuntos. Es decir, varios hilos pueden acceder y modificarlo simultáneamente.
ConcurrentHashMap proporciona métodos para operaciones en lote, como forEach(), search() y reduce().
La clase ConcurrentHashMap permite que varias operaciones de modificación se realicen de manera concurrente por varios hilos.
Por defecto, el ConcurrentHashMap se divide en16段por lo que se permite16razones para que varias hilos puedan modificar el mapeo simultáneamente. Sin embargo, se puede acceder a cualquier cantidad de hilos a la vez.
El método putIfAbsent() no sobrescribirá la entrada en el mapeo si la clave ya existe.