Clases Concurrentes Concurrenthashmap Copyonwrite
Clases Concurrentes: ConcurrentHashMap, CopyOnWriteArrayList y BlockingQueue
Java proporciona varias clases en el paquete java.util.concurrent para manejar colecciones seguras para hilos. Estas clases son diseñadas para evitar problemas de concurrencia y mejorar el rendimiento en aplicaciones multihilo. Este documento explora tres de las clases más importantes: ConcurrentHashMap, CopyOnWriteArrayList y BlockingQueue.
1. ConcurrentHashMap
ConcurrentHashMap es una implementación de Map segura para hilos que permite el acceso concurrente a sus elementos sin necesidad de sincronización explícita. Utiliza una estrategia de bloqueo segmentado para mejorar el rendimiento.
Características clave
- Acceso concurrente: Múltiples hilos pueden leer y escribir simultáneamente.
- Sin bloqueo completo: No bloquea todo el mapa para operaciones de escritura.
- Iteradores no bloqueantes: Proporciona iteradores que reflejan el estado del mapa en el momento de su creación.
Ejemplo de uso
import java.util.concurrent.ConcurrentHashMap;
public class EjemploConcurrentHashMap {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> mapa = new ConcurrentHashMap<>();
// Agregar elementos
mapa.put("A", 1);
mapa.put("B", 2);
// Actualizar valores
mapa.compute("A", (k, v) -> v + 1);
// Iterar sobre los elementos
mapa.forEach((k, v) -> System.out.println(k + ": " + v));
}
}
2. CopyOnWriteArrayList
CopyOnWriteArrayList es una implementación segura para hilos de la interfaz List. Crea una copia del array subyacente cada vez que se modifica, lo que garantiza la seguridad en entornos concurrentes.
Características clave
- Lecturas sin bloqueo: Las operaciones de lectura no necesitan sincronización.
- Copia en escritura: Las modificaciones crean una copia independiente del array.
- Iteradores seguros: Los iteradores no lanzan
ConcurrentModificationException.
Casos de uso
- Listas de configuración que cambian poco.
- Escenarios donde las lecturas son mucho más frecuentes que las escrituras.
Ejemplo de uso
import java.util.concurrent.CopyOnWriteArrayList;
public class EjemploCopyOnWriteArrayList {
public static void main(String[] args) {
CopyOnWriteArrayList<String> lista = new CopyOnWriteArrayList<>();
// Agregar elementos
lista.add("Elemento 1");
lista.add("Elemento 2");
// Iterar sobre la lista
for (String elemento : lista) {
System.out.println(elemento);
}
// Agregar mientras se itera (no lanza excepciones)
lista.add("Elemento 3");
}
}
3. BlockingQueue
BlockingQueue es una interfaz que representa una cola segura para hilos. Soporta operaciones de espera para:
- Insertar elementos cuando la cola está llena.
- Extraer elementos cuando la cola está vacía.
Implementaciones comunes
ArrayBlockingQueue: Cola con capacidad fija.LinkedBlockingQueue: Cola basada en nodos enlazados, opcionalmente con capacidad limitada.PriorityBlockingQueue: Cola basada en prioridad.
Características clave
- Bloqueo controlado: Las operaciones
putytakebloquean cuando es necesario. - Seguridad para hilos: Diseñada para entornos concurrentes.
- Sincronización automática: No se requiere sincronización manual.
Ejemplo de uso con LinkedBlockingQueue
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class EjemploBlockingQueue {
public static void main(String[] args) {
BlockingQueue<String> cola = new LinkedBlockingQueue<>(2);
// Productor
new Thread(() -> {
try {
cola.put("Elemento 1");
System.out.println("Agregado: Elemento 1");
cola.put("Elemento 2");
System.out.println("Agregado: Elemento 2");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
// Consumidor
new Thread(() -> {
try {
Thread.sleep(1000); // Simula tiempo de procesamiento
System.out.println("Tomado: " + cola.take());
System.out.println("Tomado: " + cola.take());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
}
}
4. Comparación de las Clases
| Clase | Uso principal | Ventajas | Limitaciones |
|---|---|---|---|
ConcurrentHashMap |
Mapa concurrente | Acceso rápido y seguro | Iteradores no reflejan cambios |
CopyOnWriteArrayList |
Lista concurrente con pocas escrituras | Lecturas sin bloqueo | Alto costo en escrituras |
BlockingQueue |
Cola con bloqueo | Sincronización automática | Puede bloquear indefinidamente |
5. Buenas Prácticas
- Elegir la clase adecuada: Selecciona la clase según los requisitos de concurrencia y rendimiento.
- Evitar iteradores obsoletos: Usa los iteradores proporcionados por las clases concurrentes.
- Evitar bloqueos innecesarios: Diseña sistemas para minimizar el tiempo de espera en las operaciones de bloqueo.
- Configurar capacidades: Usa capacidades adecuadas para evitar problemas de memoria o rendimiento en
BlockingQueue.
6. Conclusión
Las clases ConcurrentHashMap, CopyOnWriteArrayList y BlockingQueue son herramientas poderosas para manejar concurrencia en Java. Dominar su uso permite construir aplicaciones más seguras, eficientes y escalables en entornos multihilo.