ConcurrentHashMap vs HashMap sincronizado

148

¿Cuál es la diferencia entre usar la clase wrapper,, SynchronizedMapen a HashMapy ConcurrentHashMap?

¿Es solo poder modificar el HashMapmientras lo itera ( ConcurrentHashMap)?

hello_world_infinity
fuente

Respuestas:

120

Sincronizado HashMap:

  1. Cada método se sincroniza utilizando un bloqueo de nivel de objeto. Entonces, los métodos get y put en synchMap adquieren un bloqueo.

  2. Bloquear toda la colección es una sobrecarga de rendimiento. Mientras un hilo se aferra a la cerradura, ningún otro hilo puede usar la colección.

ConcurrentHashMap fue introducido en JDK 5.

  1. No hay bloqueo en el nivel del objeto. El bloqueo tiene una granularidad mucho más fina. Para a ConcurrentHashMap, los bloqueos pueden estar en un nivel de depósito de hashmap.

  2. El efecto del bloqueo de nivel inferior es que puede tener lectores y escritores concurrentes, lo que no es posible para colecciones sincronizadas. Esto lleva a mucha más escalabilidad.

  3. ConcurrentHashMapno arroja un ConcurrentModificationExceptionsi un hilo intenta modificarlo mientras otro está iterando sobre él.

Este artículo Java 7: HashMap vs ConcurrentHashMap es una muy buena lectura. Muy recomendable.

Joey.zhgw
fuente
77
Entonces, ¿cuál es la diferencia entre Hashtabley Synchronized HashMap?
roottraveller
1
Entre un ConcurrentHashMap y un Synchronized HashMap, ¿cuál me recomiendan?
Blunderchips
2
Vale la pena mencionar que ConcurrentHashMapel size()resultado podría estar desactualizado. size()se le permite devolver una aproximación en lugar de un recuento exacto de acuerdo con el libro "Concurrencia de Java en la práctica". Por lo tanto, este método debe usarse con cuidado.
Andrii Lisun
1
@roottraveller para Hashtable y HashMap sincronizado stackoverflow.com/questions/8875680/…
Narendra Jaggi
89

La respuesta corta:

Ambos mapas son implementaciones de la Mapinterfaz seguras para subprocesos . ConcurrentHashMapse implementa para un mayor rendimiento en casos donde se espera una alta concurrencia.

El artículo de Brian Goetz sobre la idea detrás ConcurrentHashMapes una muy buena lectura. Muy recomendable.

trshiv
fuente
1
¿Qué es esto entonces? HashMap: tenga en cuenta que esta implementación no está sincronizada para evitar el acceso no sincronizado accidental al mapa: Map m = Collections.synchronizedMap(new HashMap(...)); docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
X-HuMan
55
"El artículo de Brian Goetz ... es una muy buena lectura". - Y aún más es su libro "La concurrencia de Java en la práctica".
Alex Fedulov
31

ConcurrentHashMapes seguro para subprocesos sin sincronizar todo el mapa. Las lecturas pueden ocurrir muy rápido mientras que la escritura se realiza con un candado.

fastcodejava
fuente
18

Podemos lograr la seguridad del subproceso mediante el uso de ConcurrentHashMap y synchronizedHashmap. Pero hay mucha diferencia si nos fijamos en su arquitectura.

  1. SynchronizedHashmap

Mantendrá el bloqueo a nivel del objeto. Entonces, si desea realizar cualquier operación como poner / obtener, primero debe adquirir el bloqueo. Al mismo tiempo, otros hilos no pueden realizar ninguna operación. Entonces, a la vez, solo un hilo puede operar en esto. Entonces el tiempo de espera aumentará aquí. Podemos decir que el rendimiento es relativamente bajo cuando se compara con ConcurrentHashMap.

  1. ConcurrentHashMap

Mantendrá el bloqueo en el nivel del segmento. Tiene 16 segmentos y mantiene el nivel de concurrencia como 16 por defecto. Entonces, a la vez, 16 subprocesos pueden funcionar en ConcurrentHashMap. Además, la operación de lectura no requiere un bloqueo. Por lo tanto, cualquier número de subprocesos puede realizar una operación de obtención en él.

Si thread1 desea realizar la operación de colocación en el segmento 2 y thread2 desea realizar la operación de colocación en el segmento 4, entonces está permitido aquí. Significa que 16 subprocesos pueden realizar la operación de actualización (poner / eliminar) en ConcurrentHashMap a la vez.

Para que el tiempo de espera sea menor aquí. Por lo tanto, el rendimiento es relativamente mejor que el mapa de hash sincronizado.

Sumanth Varada
fuente
Muy buena explicación Muchas gracias
amoljdv06
11

Ambas son versiones sincronizadas de HashMap, con diferencia en su funcionalidad principal y su estructura interna.

ConcurrentHashMap consta de segmentos internos que se pueden ver como HashMaps conceptualmente independientes. Todos estos segmentos pueden ser bloqueados por hilos separados en altas ejecuciones concurrentes. Por lo tanto, varios subprocesos pueden obtener / colocar pares clave-valor de ConcurrentHashMap sin bloquearse / esperar el uno al otro. Esto se implementa para un mayor rendimiento.

mientras

Collections.synchronizedMap () , obtenemos una versión sincronizada de HashMap y se accede de forma bloqueada. Esto significa que si varios subprocesos intentan acceder a SynchronizedMap al mismo tiempo, se les permitirá obtener / colocar pares clave-valor uno a la vez de manera sincronizada.

Ashraf.Shk786
fuente
7

ConcurrentHashMaputiliza un mecanismo de bloqueo más fino conocido lock strippingpara permitir un mayor grado de acceso compartido. Debido a esto, proporciona una mejor concurrencia y escalabilidad .

También los iteradores devueltos ConcurrentHashMapson débilmente consistentes en lugar de la técnica de falla rápida utilizada por Synchronized HashMap.

rai.skumar
fuente
3

Métodos para SynchronizedMapmantener el bloqueo en el objeto, mientras que ConcurrentHashMaphay un concepto de "franjas de bloqueo" donde los bloqueos se mantienen en cubos del contenido. Por lo tanto, mejora la escalabilidad y el rendimiento.

Renukeswar
fuente
2

ConcurrentHashMap:

1) Ambos mapas son implementaciones seguras para subprocesos de la interfaz Map.

2) ConcurrentHashMap se implementa para un mayor rendimiento en casos donde se espera una alta concurrencia.

3) No hay bloqueo en el nivel del objeto.

Mapa de hash sincronizado:

1) Cada método se sincroniza utilizando un bloqueo de nivel de objeto.

NarayanaReddy
fuente
1

ConcurrentHashMap permite el acceso concurrente a los datos. Todo el mapa está dividido en segmentos.

Operación de lectura, es decir. get(Object key)no está sincronizado incluso a nivel de segmento.

Pero escribir operaciones es decir. remove(Object key), get(Object key)adquirir bloqueo a nivel de segmento. Solo parte del mapa completo está bloqueado, otros hilos aún pueden leer valores de varios segmentos excepto uno bloqueado.

SynchronizedMap por otro lado, adquiere bloqueo a nivel de objeto. Todos los hilos deben esperar al hilo actual independientemente de la operación (lectura / escritura).

Vino
fuente
1

Una prueba de rendimiento simple para ConcurrentHashMap vs Synchronized HashMap . El flujo de prueba está llamando puten un subproceso y llamando geten tres subprocesos Mapsimultáneamente. Como dijo @trshiv, ConcurrentHashMap tiene un mayor rendimiento y velocidad para cuya operación de lectura sin bloqueo. El resultado es que cuando se acaban los tiempos de operación 10^7, ConcurrentHashMap es 2xmás rápido que Synchronized HashMap.

liaoming
fuente
1

SynchronizedMapy ConcurrentHashMapambos son de clase segura para subprocesos y se pueden usar en aplicaciones multiproceso, la principal diferencia entre ellos es en cuanto a cómo logran la seguridad de los subprocesos.

SynchronizedMapadquiere bloqueo en toda la instancia de Map, mientras ConcurrentHashMapdivide la instancia de Map en múltiples segmentos y el bloqueo se realiza en esos.

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Joby Wilson Mathews
fuente
0

Según java doc's

Hashtable y Collections.synchronizedMap (new HashMap ()) están sincronizados. Pero ConcurrentHashMap es "concurrente".

Una colección concurrente es segura para subprocesos, pero no se rige por un solo bloqueo de exclusión.

En el caso particular de ConcurrentHashMap, permite de forma segura cualquier número de lecturas concurrentes, así como un número ajustable de escrituras concurrentes. Las clases "sincronizadas" pueden ser útiles cuando necesita evitar todo acceso a una colección a través de un solo bloqueo, a expensas de una escalabilidad más pobre.

En otros casos en los que se espera que varios subprocesos accedan a una colección común, normalmente son preferibles las versiones "concurrentes". Y las colecciones no sincronizadas son preferibles cuando cualquiera de las colecciones no se comparte, o son accesibles solo cuando se mantienen otros bloqueos.

Pramod
fuente