web-dev-qa-db-fra.com

Comment ConcurrentHashMap fonctionne-t-il en interne?

Je lisais la documentation officielle d'Oracle sur la concurrence en Java et je me demandais quelle pouvait être la différence entre un Collection retourné par

public static <T> Collection<T> synchronizedCollection(Collection<T> c);

et en utilisant par exemple un 

ConcurrentHashMap. Je suppose que j'utilise synchronizedCollection(Collection<T> c) sur une HashMap. Je sais qu'en général, une collection synchronisée est essentiellement un décorateur pour ma HashMap; il est donc évident qu'une ConcurrentHashMap a quelque chose de différent en interne. Avez-vous des informations sur ces détails de mise en œuvre?

Edit: je me suis rendu compte que le code source est accessible au public:ConcurrentHashMap.Java

39
Adam Arold

Je voudrais lire le source de ConcurrentHashMap car il est assez compliqué dans les détails. En bref, il a

  • Plusieurs partitions pouvant être verrouillées indépendamment. (16 par défaut)
  • Utilisation d’opérations de verrouillage simultanées pour la sécurité des tâches au lieu de la synchronisation.
  • A des itérateurs sécuritaires. Les itérateurs de synchronizedCollection ne sont pas thread-safe.
  • N'expose pas les serrures internes. synchronizedCollection fait.
40
Peter Lawrey

ConcurrentHashMap est très similaire à la classe Java.util.HashTable, sauf que ConcurrentHashMap offre une meilleure simultanéité que HashTable ou synchronizedMap. ConcurrentHashMap ne verrouille pas la carte pendant que vous la lisez. De plus, ConcurrentHashMap ne verrouille pas l'intégralité de la Maplorsque vous y écrivez. Il ne verrouille que la partie de la Map sur laquelle vous écrivez, en interne. 

Une autre différence est que ConcurrentHashMap ne jette pas ConcurrentModificationException si la ConcurrentHashMap est modifiée lors de son itération. La Iterator n'est pas conçue pour être utilisée par plus d'un thread, alors que synchronizedMap peut lancer ConcurrentModificationException 

22
amicngh

C'est l'article qui m'a aidé à le comprendre Pourquoi ConcurrentHashMap est meilleur que Hashtable et aussi bon qu'un HashMap

Hashtable offre un accès simultané à leurs entrées, avec une petite mise en garde, la carte entière est verrouillée pour effectuer toute sorte d'opération . Alors que cette surcharge est ignorable dans une application Web sous normale sous charge lourde, cela peut entraîner des retards de réponse et surtaxer votre serveur sans raison valable. 

C’est là que ConcurrentHashMap intervient. Ils offrent toutes les fonctionnalités de Hashtable avec une performance presque aussi bonne qu'un HashMap . ConcurrentHashMap y parvient par un mécanisme très simple . Au lieu d'un verrou large sur la carte, la collection conserve une liste de 16 verrouille par défaut, chacun étant utilisé pour protéger (ou verrouiller) un seul seau de la carte. Cela signifie que 16 threads peuvent modifier la collection en une seule fois (tant qu’ils travaillent tous sur des compartiments différents ). Enfait il n'y a pas d'opération effectuée par ce collection qui verrouille la carte entière. Le niveau de simultanéité du collection, le nombre de threads pouvant le modifier en même temps sans blocage, peut être augmenté. Cependant, un nombre plus élevé signifie plus frais généraux liés au maintien de cette liste de verrous.

15
gresdiplitude

Les "problèmes d’évolutivité" de Hashtable se présentent exactement de la même manière dans Collections.synchronizedMap(Map) - ils utilisent une synchronisation très simple, ce qui signifie qu’un seul thread peut accéder à la carte en même temps.

Ce n'est pas vraiment un problème lorsque vous avez de simples insertions et des recherches (sauf si vous le faites de manière extrêmement intensive), mais cela devient un gros problème lorsque vous devez parcourir l'ensemble de la carte, ce qui peut prendre beaucoup de temps pour une grande carte - un fil fait cela, tous les autres doivent attendre s'ils veulent insérer ou rechercher quoi que ce soit.

La ConcurrentHashMap utilise des techniques très sophistiquées pour réduire le besoin de synchronisation et permettre un accès en lecture parallèle à plusieurs threads sans synchronisation. Elle fournit surtout un Iterator ne nécessitant aucune synchronisation et permettant même de modifier la m si les éléments insérés lors de l'itération seront retournés).

5
MayurB

Renvoyé par synchronizedCollection () est un objet dont toutes les méthodes sont synchronisées sur this , de sorte que toutes les opérations simultanées sur cet emballage sont sérialisées. ConcurrentHashMap est un conteneur réellement simultané avec un verrouillage à grain fin optimisé pour maintenir le conflit aussi bas que possible. Regardez le code source et vous verrez ce qu’il contient.

3
bobah

ConcurrentHashMap implémente ConcurrentMap qui fournit la simultanéité . Deep en interne, ses itérateurs sont conçus pour être utilisés par un seul thread à la fois qui maintient la synchronisation . Cette carte est largement utilisée en simultanéité.

0
Manish Joshi