ConcurrentHashMap es una tabla hash que admite la concurrencia total de recuperaciones y una alta concurrencia esperada para las actualizaciones. Esta clase obedece a las mismas especificaciones funcionales que Hashtable e incluye todos los métodos de Hashtable. ConcurrentHashMap está en el paquete java.util.Concurrent.
Sintaxis:
public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V>, Serializable
Donde K se refiere al tipo de claves mantenidas por este mapa, y V se refiere al tipo de valores mapeados
Necesidad de ConcurrentHashmap:
- Aunque HashMap tiene muchas ventajas, no se puede usar para subprocesos múltiples porque no es seguro para subprocesos.
- Aunque se considera que Hashtable es seguro para subprocesos, tiene algunas desventajas. Por ejemplo, Hashtable requiere bloqueo para lectura abierta aunque no afecte al objeto.
- n HashMap, si un subproceso está iterando sobre un objeto, otro subproceso está tratando de acceder al mismo objeto, lanza ConcurrentModificationException, mientras que hashmap concurrente no lanza ConcurrentModificationException.
¿Cómo fue posible hacer que ConcurrentHashMap sea seguro para subprocesos?
- La clase java.util.Concurrent.ConcurrentHashMap logra la seguridad de subprocesos al dividir el mapa en segmentos, el bloqueo no se requiere para todo el objeto sino para un segmento, es decir, un subproceso requiere el bloqueo de un segmento.
- En ConcurrenHashap, la operación de lectura no requiere ningún bloqueo.
Ejemplo 1:
Java
// Java Program to llustarte ConcurrentModificationException // Using Normal Collections // Importing required classes import java.util.*; import java.util.concurrent.*; // Main class extending Thread class class GFG extends Thread { // Creating a static HashMap class object static HashMap m = new HashMap(); // run() method for the thread public void run() { // Try block to check for exceptions try { // Making thread to sleep for 3 seconds Thread.sleep(2000); } // Catch block to handle exceptions catch (InterruptedException e) { } // Display message System.out.println("Child Thread updating Map"); // Putting element in map m.put(103, "C"); } // Method 2 // Main driver method public static void main(String arg[]) throws InterruptedException { // Adding elements to map object created above // using put() method m.put(101, "A"); m.put(102, "B"); // Creating thread inside main() method GFG t = new GFG(); // Starting the thread t.start(); // Operating keySet() method and // storing it in Set class object Set s1 = m.keySet(); // Iterating over Set class object // using iterators Iterator itr = s1.iterator(); // Holds true till there is single element present // inside object while (itr.hasNext()) { // traversing over elements in object // using next() method Integer I1 = (Integer)itr.next(); // Print statement System.out.println( "Main Thread Iterating Map and Current Entry is:" + I1 + "..." + m.get(I1)); // Making thread to sleep for 3 seconds Thread.sleep(3000); } // Printing all elements on console System.out.println(m); } }
Producción:
Main Thread Iterating Map and Current Entry is:101...A Child Thread updating Map Exception in thread "main" java.util.ConcurrentModificationException at java.base/java.util.HashMap$HashIterator.nextNode(HashMap.java:1493) at java.base/java.util.HashMap$KeyIterator.next(HashMap.java:1516) at Main.main(Main.java:30)
Explicación de salida:
La clase utilizada en el programa anterior extiende la clase Thread. Veamos el flujo de control. Entonces, inicialmente, el programa Java anterior contiene un hilo. Cuando encontramos la declaración Main t= new Main(), estamos creando un objeto para una clase que está extendiendo la clase Thread. Por lo tanto, cada vez que llamamos al método t.start(), el subproceso secundario se activa e invoca el método run(). . Ahora el subproceso principal comienza a ejecutarse, siempre que el subproceso secundario actualice el mismo objeto de mapa, generará una excepción denominada ConcurrentModificationException.
Ahora modifiquemos el programa anterior usando ConcurrentHashMap para resolver la excepción anterior que se generó al ejecutar el programa anterior.
Ejemplo 2:
Java
// Java Program to llustarte ConcurrentModificationException // Using ConcurrentHashMap // Importing required classes import java.util.*; import java.util.concurrent.*; // Main class extending Thread class class Main extends Thread { // Creating static concurrentHashMap object static ConcurrentHashMap<Integer, String> m = new ConcurrentHashMap<Integer, String>(); // Method 1 // run() method for the thread public void run() { // Try block to check for exceptions try { // Making thread to sleep for 2 seconds Thread.sleep(2000); } // Catch block to handle the exceptions catch (InterruptedException e) { } // Display message System.out.println("Child Thread updating Map"); // Inserting element m.put(103, "C"); } // Method 2 // Main driver method public static void main(String arg[]) throws InterruptedException { // Adding elements to object created of Map m.put(101, "A"); m.put(102, "B"); // Creating thread inside main() method Main t = new Main(); // Starting thread t.start(); // Creating object of Set class Set<Integer> s1 = m.keySet(); // Creating iterator for traversal Iterator<Integer> itr = s1.iterator(); // Condition holds true till there is single element // in Set object while (itr.hasNext()) { // Iterating over elements // using next() method Integer I1 = itr.next(); // Display message System.out.println( "Main Thread Iterating Map and Current Entry is:" + I1 + "..." + m.get(I1)); // Making thread to sleep for 3 seconds Thread.sleep(3000); } // Display elements of map objects System.out.println(m); } }
Main Thread Iterating Map and Current Entry is:101...A Child Thread updating Map Main Thread Iterating Map and Current Entry is:102...B Main Thread Iterating Map and Current Entry is:103...C {101=A, 102=B, 103=C}
Explicación de salida:
la clase utilizada en el programa anterior amplía la clase Thread. Veamos el flujo de control, así como sabemos que en ConcurrentHashMap mientras un subproceso está iterando, los subprocesos restantes pueden realizar cualquier modificación de manera segura. En el programa anterior, el subproceso principal está actualizando el mapa, al mismo tiempo, el subproceso secundario también está intentando actualizar el objeto del mapa. Este Programa no generará ConcurrentModificationException.
Diferencias entre Hashtable, Hashmap, ConcurrentHashmap
Tabla de picadillo |
mapa hash |
ConcurrentHashMapConcurrentHashMap |
---|---|---|
Obtendremos Thread-safety bloqueando todo el objeto del mapa. | No es seguro para subprocesos. | Obtendremos la seguridad de subprocesos sin bloquear el objeto Total Map solo con el bloqueo de nivel de segmento. |
Cada operación de lectura y escritura requiere un bloqueo de objeto de mapa de objectstotal. | No requiere bloqueo. | Las operaciones de lectura se pueden realizar sin bloqueo, pero las operaciones de escritura se pueden realizar con bloqueo a nivel de segmento. |
A la vez, solo un subproceso puede operar en el mapa (sincronizado) | No se permite el funcionamiento de varios subprocesos a la vez. Lanzará una excepción. | A la vez, se permite que varios subprocesos operen en los objetos del mapa de manera segura. |
Mientras un subproceso itera el objeto Map, los otros subprocesos no pueden modificar el mapa; de lo contrario, obtenemos ConcurrentModificationException | Mientras un subproceso itera el objeto Map, los otros subprocesos no pueden modificar el mapa; de lo contrario, obtenemos ConcurrentModificationException | Mientras un subproceso itera el objeto Map, los otros subprocesos pueden modificar el mapa y no obtendremos ConcurrentModificationException |
Nulo no está permitido tanto para claves como para valores. | HashMap permite una clave nula y múltiples valores nulos | Nulo no está permitido tanto para claves como para valores. |
Introducido en la versión 1.0 | Introducido en la versión 1.2 | Introducido en la versión 1.5 |
Publicación traducida automáticamente
Artículo escrito por akankshakottha y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA