web-dev-qa-db-fra.com

ConcurrentHashMap vs HashMap Synchronisé

Quelle est la différence entre l'utilisation de la classe wrapper, SynchronizedMap, sur un HashMap et ConcurrentHashMap? Est-ce simplement pouvoir modifier le HashMap tout en l'itérant (ConcurrentHashMap)?

120

HashMap : synchronisé

  1. Chaque méthode est synchronisée à l'aide d'un verrou au niveau de l'objet. Donc, les méthodes get et put sur synchMap acquièrent un verrou.

  2. Verrouiller toute la collection est une surcharge de performances. Tant qu'un thread maintient le verrou, aucun autre thread ne peut utiliser la collection.

ConcurrentHashMap a été introduit dans JDK 5. 

  1. Il n'y a pas de verrouillage au niveau de l'objet. Le verrouillage est beaucoup plus fin. Pour un ConcurrentHashMap, les verrous peuvent être au niveau d'un compartiment hashmap.

  2. L'effet du verrouillage de niveau inférieur est que vous pouvez avoir des lecteurs et des écrivains simultanés, ce qui n'est pas possible pour les collections synchronisées. Cela conduit à beaucoup plus d'évolutivité.

  3. ConcurrentHashMap ne lance pas une ConcurrentModificationException si un thread tente de le modifier pendant qu'un autre itère dessus.

Cet article Java 7: HashMap vs ConcurrentHashMap est une très bonne lecture. Hautement recommandé.

93
Joey.zhgw

La réponse courte:

Les deux cartes sont des implémentations thread-safe de l'interface Map. ConcurrentHashMap est implémenté pour un débit plus élevé dans les cas où une simultanéité élevée est attendue.

Le article de Brian Goetz sur l'idée derrière ConcurrentHashMap est une très bonne lecture. Hautement recommandé.

85
trshiv

ConcurrentHashMap est thread-safe sans synchronisation de la carte entière. Les lectures peuvent être très rapides lorsque l'écriture est effectuée avec un verrou.

28
fastcodejava

Nous pouvons atteindre la sécurité des threads en utilisant à la fois ConcurrentHashMap et synchronizedHashmap. Mais il y a beaucoup de différence si vous regardez leur architecture.

  1. synchronizedHashmap

Cela maintiendra le verrou au niveau de l'objet. Donc, si vous souhaitez effectuer une opération telle que put/get, vous devez d'abord acquérir le verrou. Dans le même temps, les autres threads ne sont autorisés à effectuer aucune opération. Donc, à la fois, un seul thread peut fonctionner sur cela. Donc, le temps d'attente augmentera ici. Nous pouvons dire que les performances sont relativement faibles lorsque vous comparez avec ConcurrentHashMap.

  1. ConcurrentHashMap

Il maintiendra le verrou au niveau du segment. Il comporte 16 segments et maintient le niveau de concurrence de 16 par défaut. Donc, à la fois, 16 threads peuvent fonctionner sur ConcurrentHashMap. De plus, l'opération de lecture ne nécessite pas de verrouillage. Donc, n'importe quel nombre de threads peuvent effectuer une opération get sur celui-ci. 

Si thread1 veut effectuer une opération de vente dans le segment 2 et que thread2 souhaite effectuer une opération de vente sur le segment 4, il est autorisé à le faire ici. Cela signifie que 16 threads peuvent effectuer une opération de mise à jour (insertion/suppression) sur ConcurrentHashMap à la fois.

Alors que le temps d'attente sera moins ici. Par conséquent, les performances sont relativement meilleures que synchronizedHashmap.

9
Sumanth Varada

Les deux sont une version synchronisée de HashMap, avec des fonctionnalités différentes et une structure interne différente.

ConcurrentHashMap est constitué de segments internes pouvant être considérés comme des HashMaps indépendants Conceptuellement . Tous ces segments peuvent être verrouillés par des threads distincts lors d'exécutions simultanées élevées . de ConcurrentHashMap sans se bloquer/attendre les uns des autres . Ceci est implémenté pour un débit plus élevé.

tandis que

Collections.synchronizedMap () , nous obtenons une version synchronisée de HashMap à laquelle on accède de manière bloquante. Cela signifie que si plusieurs threads tentent d'accéder à synchronizedMap en même temps, ils seront autorisés à obtenir/mettre des paires clé-valeur une par une de manière synchronisée.

9
Ashraf.Shk786

ConcurrentHashMap utilise un mécanisme de verrouillage à grain plus fin, appelé lock stripping, pour permettre un plus grand accès partagé. De ce fait, il offre une meilleure concurrence et une évolutivité .

Les itérateurs renvoyés pour ConcurrentHashMap sont également faiblement cohérent au lieu de technique d'échec rapide utilisé par Synchronized HashMap. 

7
rai.skumar

Les méthodes sur SynchronizedMap maintiennent le verrou sur l'objet, alors que dans ConcurrentHashMap, il existe un concept de "bande de verrouillage" dans lequel les verrous sont maintenus sur des compartiments du contenu. Ainsi, l'évolutivité et les performances ont été améliorées. 

3
Renukeswar

ConcurrentHashMap:

1) Les deux cartes sont des implémentations thread-safe de l'interface Map.

2) ConcurrentHashMap est implémenté pour un débit plus élevé dans les cas où une simultanéité élevée est attendue. 

3) Il n'y a pas de verrouillage au niveau de l'objet. 

Carte de hachage synchronisée:

1) Chaque méthode est synchronisée à l'aide d'un verrou au niveau de l'objet. 

2
NarayanaReddy

Un test de performance simple pour ConcurrentHashMap vs Synchronized HashMap . Le flux de test appelle put dans un thread et get dans trois threads sur Map simultanément. Comme @trshiv l'a dit, ConcurrentHashMap a un débit et une vitesse plus élevés pour les opérations de lecture sans verrouillage. Le résultat est que, lorsque l'opération a dépassé 10^7, ConcurrentHashMap est 2x plus rapide que Synchronized HashMap.

1
liaoming

Selon le document Java

Hashtable et Collections.synchronizedMap (nouveaux HashMap ()) sont synchronisé. Mais ConcurrentHashMap est "simultané". 

Une collection simultanée est sécurisée pour les threads, mais non régie par un seul verrou d'exclusion. 

Dans le cas particulier de ConcurrentHashMap, il permet en toute sécurité un nombre quelconque de lectures simultanées ainsi qu'un nombre ajustable de écrit simultané. Les classes "synchronisées" peuvent être utiles lorsque vous avez besoin de pour empêcher tout accès à une collection via un seul verrou, au niveau du fichier frais de moins bonne évolutivité. 

Dans les autres cas dans lesquels plusieurs les threads doivent accéder à une collection commune, "concurrente" les versions sont normalement préférables. Et les collections non synchronisées sont préférable lorsque les collections ne sont pas partagées ou sont accessibles seulement en tenant d'autres serrures.

0
Pramod

ConcurrentHashMapautorise l'accès simultané aux données. Toute la carte est divisée en segments. 

Opération de lecture get(Object key) n'est pas synchronisé même au niveau du segment. 

Mais écrivez des opérations à savoir. remove(Object key), get(Object key) acquiert un verrou au niveau du segment. Seule une partie de la carte entière est verrouillée, les autres threads peuvent toujours lire les valeurs de différents segments, sauf le verrouillé.

SynchronizedMap d’autre part, acquiert un verrou au niveau de l’objet. Tous les threads doivent attendre le thread actuel indépendamment de l'opération (lecture/écriture).

0
Vino