¿Cuál es la diferencia entre usar la clase wrapper,, SynchronizedMap
en a HashMap
y ConcurrentHashMap
?
¿Es solo poder modificar el HashMap
mientras lo itera ( ConcurrentHashMap
)?
¿Cuál es la diferencia entre usar la clase wrapper,, SynchronizedMap
en a HashMap
y ConcurrentHashMap
?
¿Es solo poder modificar el HashMap
mientras lo itera ( ConcurrentHashMap
)?
Respuestas:
Sincronizado HashMap
:
Cada método se sincroniza utilizando un bloqueo de nivel de objeto. Entonces, los métodos get y put en synchMap adquieren un bloqueo.
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.
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.
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.
ConcurrentHashMap
no arroja un ConcurrentModificationException
si 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.
ConcurrentHashMap
el 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.
La respuesta corta:
Ambos mapas son implementaciones de la Map
interfaz seguras para subprocesos . ConcurrentHashMap
se implementa para un mayor rendimiento en casos donde se espera una alta concurrencia.
El artículo de Brian Goetz sobre la idea detrás ConcurrentHashMap
es una muy buena lectura. Muy recomendable.
Map m = Collections.synchronizedMap(new HashMap(...));
docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
ConcurrentHashMap
es seguro para subprocesos sin sincronizar todo el mapa. Las lecturas pueden ocurrir muy rápido mientras que la escritura se realiza con un candado.
Podemos lograr la seguridad del subproceso mediante el uso de ConcurrentHashMap y synchronizedHashmap. Pero hay mucha diferencia si nos fijamos en su arquitectura.
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.
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.
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.
ConcurrentHashMap
utiliza un mecanismo de bloqueo más fino conocido lock stripping
para permitir un mayor grado de acceso compartido. Debido a esto, proporciona una mejor concurrencia y escalabilidad .
También los iteradores devueltos ConcurrentHashMap
son débilmente consistentes en lugar de la técnica de falla rápida utilizada por Synchronized HashMap.
Métodos para SynchronizedMap
mantener el bloqueo en el objeto, mientras que ConcurrentHashMap
hay un concepto de "franjas de bloqueo" donde los bloqueos se mantienen en cubos del contenido. Por lo tanto, mejora la escalabilidad y el rendimiento.
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.
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).
Una prueba de rendimiento simple para ConcurrentHashMap vs Synchronized HashMap
. El flujo de prueba está llamando put
en un subproceso y llamando get
en tres subprocesos Map
simultá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 2x
más rápido que Synchronized HashMap.
SynchronizedMap
y ConcurrentHashMap
ambos 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.
SynchronizedMap
adquiere bloqueo en toda la instancia de Map, mientras ConcurrentHashMap
divide la instancia de Map en múltiples segmentos y el bloqueo se realiza en esos.
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.
Hashtable
ySynchronized HashMap
?