Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprende ConcurrentMap y Sus Implementaciones | Colecciones Sincronizadas
Multithreading en Java

bookConcurrentMap y Sus Implementaciones

Ejemplo de la vida real

Una aplicación web utiliza ConcurrentMap para almacenar en caché datos solicitados con frecuencia, como sesiones de usuario. Diferentes hilos pueden actualizar y leer datos del mapa simultáneamente, garantizando acceso rápido y operaciones seguras.

Diferencias con otros tipos

  • Seguridad en un entorno multihilo: ConcurrentMap gestiona automáticamente la sincronización de accesos a los datos, mientras que en un Map convencional esta tarea debe realizarse manualmente;
  • Eficiencia: Permite lectura y escritura de datos en paralelo sin bloquear toda la estructura de datos.

Implementaciones de ConcurrentMap

ConcurrentHashMap: Permite el soporte eficiente de múltiples hilos dividiendo el mapa en segmentos (buckets), lo que posibilita la ejecución paralela de operaciones sin bloquear todo el mapa.

Sintaxis

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<>();

ConcurrentHashMap en Java divide los datos en múltiples buckets, cada uno gestionado por un monitor independiente. Esta configuración permite que diferentes hilos modifiquen o lean datos de distintos buckets simultáneamente, lo que mejora el rendimiento.

Los hilos pueden acceder a los buckets en paralelo, reduciendo bloqueos y evitando condiciones de carrera.

Cada bucket contiene registros en forma de pares clave-valor, que pueden organizarse como listas enlazadas.

ConcurrentSkipListMap: Una implementación basada en skip-list que soporta el ordenamiento sorted de claves. Proporciona inserción, eliminación y acceso a datos rápidos en un entorno multihilo.

Sintaxis

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentSkipListMap = new ConcurrentSkipListMap<>();

📝Inserción: Cuando se agrega un nuevo elemento a ConcurrentSkipListMap, comienza en el nivel más bajo. Luego asciende a través de los niveles hasta que se coloca donde sus claves y valores están en el orden correcto.

🔍Búsqueda: Para encontrar un elemento por clave, ConcurrentSkipListMap comienza en el nodo principal del nivel superior. Sigue los punteros hasta localizar un nodo con una clave igual o mayor que la clave de búsqueda.

❌Eliminación: Para eliminar un elemento de ConcurrentSkipListMap, primero se elimina del nivel más bajo. Luego se degrada a través de los niveles hasta que se elimina de donde sus claves y valores están correctamente ordenados.

Ejemplo de uso de ConcurrentMap en código

Métodos principales

putIfAbsent(K key, V value): Agrega un par clave-valor al mapa solo si la clave no está presente.

Main.java

Main.java

copy
123
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.putIfAbsent("a", 1); // Adds the pair ("a", 1) to the map, as "a" is not already present map.putIfAbsent("a", 2); // Does not change the value, as "a" is already present in the map

remove(Object key, Object value): Elimina el par clave-valor si la clave está asociada al valor especificado.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.remove("a", 1); // Removes the pair ("a", 1), as "a" is mapped to value 1 map.remove("a", 2); // Does nothing, as "a" is not mapped to value 2

replace(K key, V value): Reemplaza la entrada para una clave solo si actualmente está asociada a algún valor.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.replace("a", 2); // Replaces the value 1 with 2 for key "a" map.replace("b", 3); // Does nothing, as "b" is not present

compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction): Calcula un nuevo valor para la clave especificada utilizando la función de reasignación proporcionada, lo que puede implicar crear un nuevo valor, modificar o eliminar el valor existente.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.compute("a", (k, v) -> v == null ? 1 : v + 1); // Increases the value for key "a" by 1 map.compute("b", (k, v) -> v == null ? 1 : v + 1); // Sets the value to 1 for new key "b"

merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction): Fusiona el valor dado con el valor existente asociado a la clave utilizando la función de reasignación proporcionada, lo que facilita la agregación de datos.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.merge("a", 2, Integer::sum); // Sums the current value (1) with the new value (2), resulting in 3 map.merge("b", 2, Integer::sum); // Sets the value to 2 for new key "b"

getOrDefault(Object key, V defaultValue) - devuelve el valor asociado con la clave especificada, o el valor predeterminado si la clave no está presente.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); int value1 = map.getOrDefault("a", 0); // Returns 1, as "a" is present int value2 = map.getOrDefault("b", 0); // Returns 0, as "b" is not present

😔 Limitaciones

Una de las posibles desventajas es la inestabilidad en el orden, ya que algunas implementaciones podrían no garantizar el orden de los elementos durante la iteración. Además, puede haber soporte limitado para ciertas operaciones; por ejemplo, las actualizaciones condicionales atómicas pueden no estar completamente soportadas en algunas implementaciones.

💪 Ventajas

Por otro lado, el alto rendimiento es un beneficio clave, lo que lo hace adecuado para escenarios que implican operaciones intensivas de lectura y escritura. También ofrece facilidad de uso, reduciendo significativamente la necesidad de una gestión manual de la sincronización en un entorno multihilo.

1. ¿Cuál es el propósito de ConcurrentMap?

2. ¿Cuál de las siguientes es una implementación segura para hilos de ConcurrentMap?

3. ¿Cómo garantiza ConcurrentHashMap la seguridad para hilos?

question mark

¿Cuál es el propósito de ConcurrentMap?

Select the correct answer

question mark

¿Cuál de las siguientes es una implementación segura para hilos de ConcurrentMap?

Select the correct answer

question mark

¿Cómo garantiza ConcurrentHashMap la seguridad para hilos?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 2. Capítulo 5

Pregunte a AI

expand

Pregunte a AI

ChatGPT

Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla

Awesome!

Completion rate improved to 3.33

bookConcurrentMap y Sus Implementaciones

Desliza para mostrar el menú

Ejemplo de la vida real

Una aplicación web utiliza ConcurrentMap para almacenar en caché datos solicitados con frecuencia, como sesiones de usuario. Diferentes hilos pueden actualizar y leer datos del mapa simultáneamente, garantizando acceso rápido y operaciones seguras.

Diferencias con otros tipos

  • Seguridad en un entorno multihilo: ConcurrentMap gestiona automáticamente la sincronización de accesos a los datos, mientras que en un Map convencional esta tarea debe realizarse manualmente;
  • Eficiencia: Permite lectura y escritura de datos en paralelo sin bloquear toda la estructura de datos.

Implementaciones de ConcurrentMap

ConcurrentHashMap: Permite el soporte eficiente de múltiples hilos dividiendo el mapa en segmentos (buckets), lo que posibilita la ejecución paralela de operaciones sin bloquear todo el mapa.

Sintaxis

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<>();

ConcurrentHashMap en Java divide los datos en múltiples buckets, cada uno gestionado por un monitor independiente. Esta configuración permite que diferentes hilos modifiquen o lean datos de distintos buckets simultáneamente, lo que mejora el rendimiento.

Los hilos pueden acceder a los buckets en paralelo, reduciendo bloqueos y evitando condiciones de carrera.

Cada bucket contiene registros en forma de pares clave-valor, que pueden organizarse como listas enlazadas.

ConcurrentSkipListMap: Una implementación basada en skip-list que soporta el ordenamiento sorted de claves. Proporciona inserción, eliminación y acceso a datos rápidos en un entorno multihilo.

Sintaxis

Main.java

Main.java

copy
1
ConcurrentMap<Integer, Integer> concurrentSkipListMap = new ConcurrentSkipListMap<>();

📝Inserción: Cuando se agrega un nuevo elemento a ConcurrentSkipListMap, comienza en el nivel más bajo. Luego asciende a través de los niveles hasta que se coloca donde sus claves y valores están en el orden correcto.

🔍Búsqueda: Para encontrar un elemento por clave, ConcurrentSkipListMap comienza en el nodo principal del nivel superior. Sigue los punteros hasta localizar un nodo con una clave igual o mayor que la clave de búsqueda.

❌Eliminación: Para eliminar un elemento de ConcurrentSkipListMap, primero se elimina del nivel más bajo. Luego se degrada a través de los niveles hasta que se elimina de donde sus claves y valores están correctamente ordenados.

Ejemplo de uso de ConcurrentMap en código

Métodos principales

putIfAbsent(K key, V value): Agrega un par clave-valor al mapa solo si la clave no está presente.

Main.java

Main.java

copy
123
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.putIfAbsent("a", 1); // Adds the pair ("a", 1) to the map, as "a" is not already present map.putIfAbsent("a", 2); // Does not change the value, as "a" is already present in the map

remove(Object key, Object value): Elimina el par clave-valor si la clave está asociada al valor especificado.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.remove("a", 1); // Removes the pair ("a", 1), as "a" is mapped to value 1 map.remove("a", 2); // Does nothing, as "a" is not mapped to value 2

replace(K key, V value): Reemplaza la entrada para una clave solo si actualmente está asociada a algún valor.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.replace("a", 2); // Replaces the value 1 with 2 for key "a" map.replace("b", 3); // Does nothing, as "b" is not present

compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction): Calcula un nuevo valor para la clave especificada utilizando la función de reasignación proporcionada, lo que puede implicar crear un nuevo valor, modificar o eliminar el valor existente.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.compute("a", (k, v) -> v == null ? 1 : v + 1); // Increases the value for key "a" by 1 map.compute("b", (k, v) -> v == null ? 1 : v + 1); // Sets the value to 1 for new key "b"

merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction): Fusiona el valor dado con el valor existente asociado a la clave utilizando la función de reasignación proporcionada, lo que facilita la agregación de datos.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); map.merge("a", 2, Integer::sum); // Sums the current value (1) with the new value (2), resulting in 3 map.merge("b", 2, Integer::sum); // Sets the value to 2 for new key "b"

getOrDefault(Object key, V defaultValue) - devuelve el valor asociado con la clave especificada, o el valor predeterminado si la clave no está presente.

Main.java

Main.java

copy
1234
ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("a", 1); int value1 = map.getOrDefault("a", 0); // Returns 1, as "a" is present int value2 = map.getOrDefault("b", 0); // Returns 0, as "b" is not present

😔 Limitaciones

Una de las posibles desventajas es la inestabilidad en el orden, ya que algunas implementaciones podrían no garantizar el orden de los elementos durante la iteración. Además, puede haber soporte limitado para ciertas operaciones; por ejemplo, las actualizaciones condicionales atómicas pueden no estar completamente soportadas en algunas implementaciones.

💪 Ventajas

Por otro lado, el alto rendimiento es un beneficio clave, lo que lo hace adecuado para escenarios que implican operaciones intensivas de lectura y escritura. También ofrece facilidad de uso, reduciendo significativamente la necesidad de una gestión manual de la sincronización en un entorno multihilo.

1. ¿Cuál es el propósito de ConcurrentMap?

2. ¿Cuál de las siguientes es una implementación segura para hilos de ConcurrentMap?

3. ¿Cómo garantiza ConcurrentHashMap la seguridad para hilos?

question mark

¿Cuál es el propósito de ConcurrentMap?

Select the correct answer

question mark

¿Cuál de las siguientes es una implementación segura para hilos de ConcurrentMap?

Select the correct answer

question mark

¿Cómo garantiza ConcurrentHashMap la seguridad para hilos?

Select the correct answer

¿Todo estuvo claro?

¿Cómo podemos mejorarlo?

¡Gracias por tus comentarios!

Sección 2. Capítulo 5
some-alt