Aprende a usar java.util.concurrent.ConcurrentHashMap fácilmente en Java

| Última modificación: 23 de enero de 2025 | Tiempo de Lectura: 3 minutos

Algunos de nuestros reconocimientos.:

Yo me sentía el más de malas cuando empecé a trabajar con las aplicaciones multihilo, porque siempre me sucedía algo inesperado. Recuerdo que una vez me di cuenta de que los datos compartidos entre los hilos se volvían difíciles de manejar y, como si fuera poco, también ralentizaban todo el sistema. Por fortuna me enseñaron a usar java.util.concurrent.ConcurrentHashMap, así que la situación cambió al manejar datos compartidos, porque no había necesidad de sacrificar el rendimiento. Desde ya te digo que no seas como yo, que empecé usando un HashMap y solo me sirvió para darme cuenta de que no era seguro para hilos y generaba errores muy difíciles de rastrear.

java.util.concurrent.ConcurrentHashMap qué es

¿Qué es java.util.concurrent.ConcurrentHashMap?

Quiero plantearte este escenario para que entiendas bien el concepto de ConcurrentHashMap: Hazte una imagen mental de una biblioteca enorme con miles de libros, donde varios bibliotecarios tienen que organizarlos simultáneamente.

Entonces, ¿qué pasaría si cada bibliotecario tuviera que bloquear toda la biblioteca cada que vaya a organizar un estante? Exacto, solo verías caos por todas partes . Por eso, el “bloqueo por segmentos” que te proporciona java.util.concurrent.ConcurrentHashMap es la solución perfecta. Gracias a esto, cada bibliotecario puede trabajar en una sección específica sin interferir con los demás.

Siendo más concretos, ConcurrentHashMap es una implementación de Map segura para hilos que hace parte de java.util.concurrent. Con ella múltiples hilos pueden leer y escribir datos simultáneamente sin bloquear el mapa completo, gracias a su mecanismo de segmentación. Es excelente para aplicaciones donde el acceso concurrente es constante y crítico.

Ventajas de ConcurrentHashMap

  1. Escalabilidad mejorada: Gracias a su mecanismo de bloqueo por segmentos, los hilos solo bloquean una parte específica del mapa.
  2. Operaciones atómicas: Métodos como putIfAbsent() y replace() garantizan consistencia en operaciones concurrentes.
  3. Eficiencia en lecturas: Las lecturas no requieren bloqueo, permitiendo acceso simultáneo sin interrupciones.
  4. Mayor rendimiento: En comparación con Hashtable, su diseño permite una ejecución más rápida bajo carga concurrente.

Características

  1. Sin claves o valores nulos: Verás que si intentas agregar un elemento nulo, te generará una excepción.
  2. Manejo eficiente de hilos: Usa bloqueos a nivel de segmentos o buckets, lo que permite múltiples operaciones concurrentes.
  3. Métodos útiles para concurrencia: Métodos como computeIfAbsent() simplifican tareas comunes en entornos multihilo.

Cómo funciona java.util.concurrent.ConcurrentHashMap

Gestionando sistemas

Supongamos que gestionas un sistema donde los usuarios acceden simultáneamente a datos compartidos. Así es como puedes usar una ConcurrentHashMap para manejarlo:

import java.util.concurrent.ConcurrentHashMap;

public class EjemploConcurrentHashMap {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> inventario = new ConcurrentHashMap<>();

// Agregar productos al inventario
inventario.put("Manzanas", 50);
inventario.put("Naranjas", 30);

// Consultar inventario
System.out.println("Inventario inicial: " + inventario);

// Actualizar existencias de forma segura
inventario.compute("Manzanas", (key, val) -> (val == null) ? 10 : val + 20);

// Agregar un producto si no existe
inventario.putIfAbsent("Peras", 25);

// Eliminar un producto de forma condicional
inventario.remove("Naranjas", 30);

System.out.println("Inventario actualizado: " + inventario);
}
}

Mira la salida:

Inventario inicial: {Manzanas=50, Naranjas=30}
Inventario actualizado: {Manzanas=70, Peras=25}

Contador de visitas por página

Ahora piensa que tienes un sitio web y quieres registrar cuántas veces se visita cada página. Puedes hacerlo fácilmente con una ConcurrentHashMap:

import java.util.concurrent.ConcurrentHashMap;

public class ContadorVisitas {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> visitas = new ConcurrentHashMap<>();

// Incrementar visitas por página
visitas.compute("Inicio", (key, val) -> (val == null) ? 1 : val + 1);
visitas.compute("Contacto", (key, val) -> (val == null) ? 1 : val + 1);
visitas.compute("Inicio", (key, val) -> (val == null) ? 1 : val + 1);

System.out.println("Visitas por página: " + visitas);
}
}

Esta es la salida esperada:

Visitas por página: {Inicio=2, Contacto=1}

Diferencias contundentes entre ConcurrentHashMap y Hashtable

Quiero explicarte que, aunque ambos son seguros para hilos, ConcurrentHashMap supera por mucho a Hashtable en varios aspectos:

PropiedadConcurrentHashMapHashtable
Nivel de bloqueoBloqueo por segmentosBloqueo completo del mapa
RendimientoMejor bajo alta concurrenciaMás lento debido a sincronización
Permite valores nulosNoNo

Ya te queda claro que, el uso de java.util.concurrent.ConcurrentHashMap es super necesario cuando trabajas con aplicaciones multihilo que necesitan manejar datos compartidos. Además, así te evitarás esos molestos problemas como la inconsistencia de datos o errores de sincronización, que ocurren bastante en estructuras como HashMap.

Tengo el presentimiento de que quieres aprender más sobre estas herramientas y convertirte en un desarrollador experto en Java, ¿no es así? Pues simplemente únete a nuestro Bootcamp de Java Full Stack en KeepCoding. Con nosotros aprenderás a construir aplicaciones complejas, manejar la concurrencia y optimizar el rendimiento como un profesional. ¡Tu futuro en el sector IT comienza aquí!

Posts más leídos