Quelle est la différence entre ConcurrentHashMap et des Collections.synchronizedMap(Map)?
J'ai une Carte qui est d'être modifié par plusieurs threads simultanément.
Il semble y avoir trois différentes synchronisé Carte implémentations de l'API Java:
Hashtable
Collections.synchronizedMap(Map)
ConcurrentHashMap
De ce que je comprends, Hashtable
est un vieux de la mise en œuvre (l'extension de l'obsolètes Dictionary
classe), qui a été adapté plus tard, pour s'adapter à la Map
interface. Alors qu'il est synchronisé, il semble avoir de graves les problèmes d'évolutivité et est déconseillé pour les nouveaux projets.
Mais ce que sur les deux autres? Quelles sont les différences entre les Cartes retournées par Collections.synchronizedMap(Map)
et ConcurrentHashMap
s? Ce qui correspond à une situation qui?
- Link est actuellement cassé, ici est une copie archivée de cet article: Pourquoi ConcurrentHashMap est mieux que la table de hachage et tout aussi bon comme un HashMap
- IBM: Comment ConcurrentHashMap offre de plus de simultanéité sans compromettre la sécurité des threads @ ibm.com/developerworks/java/library/j-jtp08223/...
Vous devez vous connecter pour publier un commentaire.
Pour vos besoins, utilisez
ConcurrentHashMap
. Il permet une modification concurrente de la Carte à partir de plusieurs threads sans la nécessité pour les bloquer.Collections.synchronizedMap(map)
crée un blocage de la Carte qui va dégrader les performances, mais de s'assurer de la cohérence (si utilisé correctement).Utiliser la deuxième option si vous avez besoin de s'assurer de la cohérence des données, et chaque thread doit avoir une mise à jour de la carte. Utiliser le premier si la performance est critique, et chaque thread n'insère des données à la carte, avec lit produisent moins fréquemment.
Collections.synchronizedMap(map)
crée un blocage de la Carte qui va dégrader les performances, mais de s'assurer de la cohérence (si utilisé correctement)": n'Est pas la créationMap m = Collections.synchronizedMap(new HashMap(...))
suffisante pour assurer la cohérence? Est-il autre chose que j'ai besoin d'être au courant?Concernant le mécanisme de verrouillage:
Hashtable
verrouille l'objet, tandis queConcurrentHashMap
serrures seul le seau.Hashtable
n'est pas de verrouillage de la partie de la carte. Regardez la mise en œuvre. C'est à l'aide desynchronized
clé sans verrouillage fourni de manière à ce qu'il signifie qu'il permet de verrouiller l'ensemblehashtable
dans chaque opération.Les "problèmes d'évolutivité" pour
Hashtable
sont présents dans exactement de la même manière dansCollections.synchronizedMap(Map)
- ils d'un usage très simple de synchronisation, ce qui signifie qu'un seul thread peut accéder à la carte en même temps.Ce n'est pas vraiment un problème si vous avez simple, les inserts et les recherches (sauf si vous le faites extrêmement intensive), mais devient un gros problème quand vous en avez besoin pour effectuer une itération sur l'ensemble de la Carte, ce qui peut prendre beaucoup de temps pour une grande Carte, alors que l'un thread n'est que, tous les autres ont à attendre si ils veulent insérer ou à la recherche de quoi que ce soit.
La
ConcurrentHashMap
utilise des techniques sophistiquées pour réduire la nécessité pour la synchronisation et en parallèle de l'accès en lecture par plusieurs threads sans synchronisation et, plus important encore, fournit uneIterator
qui ne nécessite pas de synchronisation et permet même à la Carte d'être modifiées en cours d'interaction (même si elle ne garantit pas de savoir si ou non les éléments qui ont été insérés au cours d'une itération sera retourné).ConcurrentHashMap est préférable si vous pouvez l'utiliser même si elle nécessite au moins la version Java 5.
Il est conçu à l'échelle ainsi lorsqu'il est utilisé par plusieurs threads. Les performances peuvent être légèrement plus pauvres lorsqu'un seul thread accède à la Carte à un moment, mais nettement mieux lorsque plusieurs threads accèdent à la carte en même temps.
J'ai trouvé un l'entrée de blog qui reproduit un tableau de l'excellent livre Java De La Simultanéité Dans La Pratique, que je recommande absolument.
Collections.synchronizedMap sens vraiment que si vous avez besoin d'envelopper de la carte avec certaines autres caractéristiques, peut-être une sorte de commandé la carte, comme un TreeMap.
La principale différence entre ces deux, c'est que
ConcurrentHashMap
de verrouillage, seulement partie des données qui sont en train d'être mis à jour pendant l'autre partie des données peut être consultée par d'autres threads. Cependant,Collections.synchronizedMap()
de verrouillage, toutes les données de mise à jour, les autres threads ne peuvent accéder aux données lorsque le verrou est libéré. Si il y a de nombreuses opérations de mise à jour et la relative petite quantité d'opérations de lecture, vous devez choisirConcurrentHashMap
.Aussi une autre différence est que
ConcurrentHashMap
ne permet pas de conserver l'ordre des éléments dans la Carte passée. Il est semblable àHashMap
lors du stockage des données. Il n'y a aucune garantie que l'élément de commande est conservée. Alors queCollections.synchronizedMap()
permettra de préserver les éléments de commande de la Carte passée. Par exemple, si vous passez unTreeMap
àConcurrentHashMap
, les éléments de l'ordre dans leConcurrentHashMap
ne peut pas être le même que l'ordre dans laTreeMap
, maisCollections.synchronizedMap()
permettra de préserver l'ordre.En outre,
ConcurrentHashMap
peut garantir qu'il n'y a pas deConcurrentModificationException
jeté alors qu'un thread est la mise à jour de la carte et un autre thread est de la traversée de l'itérateur obtenu à partir de la carte. Cependant,Collections.synchronizedMap()
n'est pas garanti sur ce.Il est un post qui montrent les différences de ces deux et aussi le
ConcurrentSkipListMap
.Hashtable
etConcurrentHashMap
ne permettent pasnull
clés ounull
valeurs.Collections.synchronizedMap(Map)
synchronise tous opérations (get
,put
,size
, etc).ConcurrentHashMap
prise en charge de la concurrence des récupérations, et réglable de simultanéité prévu pour les mises à jour.Comme d'habitude, il y a simultanéité-les frais généraux--vitesse de concessions à faire. Vous avez vraiment besoin de considérer le détail de la simultanéité des exigences de votre application pour prendre une décision, puis de tester votre code pour voir si elle est assez bonne.
Dans
ConcurrentHashMap
, la serrure est appliqué à un segment au lieu de la totalité d'une Carte.Chaque segment gère son propre table de hachage interne. La serrure est appliquée uniquement pour les opérations de mise à jour.
Collections.synchronizedMap(Map)
synchronise l'ensemble de la carte.Synchronisé Carte:
Synchronisé Carte est également pas très différent de la table de hachage et offre des performances similaires en simultané de programmes Java. Seule différence entre la table de hachage et SynchronizedMap est que SynchronizedMap n'est pas un héritage et que vous pouvez placer n'importe quelle Carte de créer il est synchronisé version à l'aide de Collections.synchronizedMap() la méthode.
ConcurrentHashMap:
La ConcurrentHashMap classe fournit en même temps une version de la norme HashMap. C'est une amélioration sur le synchronizedMap fonctionnalités fournies dans les Collections de la classe.
Contrairement à la table de hachage et la synchronisation de la Carte, il n'a jamais serrures ensemble de la Carte, au lieu de cela, il divise la carte en segments et le verrouillage se fait sur ceux-ci. Il fonctionnera mieux si le nombre de threads de lecture sont plus importants que le nombre de threads d'écriture.
ConcurrentHashMap par défaut est divisé en 16 régions et les serrures sont appliquées. Cette valeur par défaut peut être défini lors de l'initialisation d'un ConcurrentHashMap instance. Lors de la configuration de données dans un segment particulier, le blocage de ce segment est obtenu. Cela signifie que deux mises à jour peuvent toujours exécuter simultanément en toute sécurité si ils affectent distinct des seaux, et donc la réduction de verrouillage et ainsi de maximiser le rendement.
ConcurrentHashMap ne jette pas un ConcurrentModificationException
ConcurrentHashMap ne jette pas un ConcurrentModificationException si un thread tente de modifier tandis que l'autre est une itération de plus il
Différence entre synchornizedMap et ConcurrentHashMap
Collections.synchornizedMap(HashMap) va retourner une collection qui est presque l'équivalent de la table de hachage, où chaque opération sur la Carte est verrouillée sur la Carte de l'objet, tandis que dans le cas de ConcurrentHashMap, le fil de sécurité est obtenu en divisant l'ensemble de la Carte dans différents partition basée sur niveau de simultanéité et seulement verrouillage notamment partie à la place de verrouillage de la totalité de la Carte.
ConcurrentHashMap ne pas autoriser les valeurs null clés ou des valeurs nulles, tout synchronisé HashMap permet clés null.
Liens similaires
Link1
Link2
Comparaison Des Performances
Vous avez raison sur
HashTable
, vous pouvez l'oublier.Votre article mentionne le fait que, bien que la table de hachage et synchronisée de classe wrapper de base de thread de sécurité en permettant seulement à un seul thread à la fois pour accéder à la carte, ce n'est pas le "vrai" fil de sécurité depuis de nombreuses opérations composées de toujours exiger un complément de synchronisation, par exemple:
Cependant, ne pensez pas que
ConcurrentHashMap
est une alternative simple pour unHashMap
avec un typiquesynchronized
bloc comme indiqué ci-dessus. Lire cette article pour comprendre les subtilités du mieux.Voici quelques-uns :
1) ConcurrentHashMap verrouille uniquement la partie de la Carte, mais SynchronizedMap serrures ensemble de la Carte.
2) ConcurrentHashMap a une meilleure performance sur SynchronizedMap et plus évolutif.
3) En cas de pluralité de lecteur et de l'écrivain ConcurrentHashMap est le meilleur choix.
Ce texte est de Différence entre ConcurrentHashMap et table de hachage en Java
Nous pouvons parvenir à la sécurité des threads en utilisant ConcurrentHashMap et synchronisedHashmap et de la table de hachage. Mais il y a beaucoup de différence si vous regardez leur architecture.
ConcurrentHashMap
SynchronizedHashMap
source
ConcurrentHashMap est optimisé pour les accès simultanés.
Accède à ne pas verrouiller l'ensemble de la carte mais l'utilisation d'une plus fine de la stratégie, ce qui améliore l'évolutivité. Il y a aussi fonctionnelle enhanvements spécifiquement pour l'accès simultané, par exemple simultanées des itérateurs.
Il y a une critique de la fonction à noter à propos de
ConcurrentHashMap
autres que la simultanéité fonctionnalités qu'il propose, qui est fail-safe itérateur. J'ai vu des développeurs utilisantConcurrentHashMap
simplement parce qu'ils veulent modifier la entryset - mettre/enlever lors de l'itération sur elle.Collections.synchronizedMap(Map)
ne fournit pas de fail-safe itérateur, mais il fournit fail-fast itérateur à la place. fail-fast itérateurs utilise instantané de la taille de la carte qui ne peut pas être modifié au cours d'une itération.En général, si vous souhaitez utiliser le
ConcurrentHashMap
assurez-vous que vous êtes prêt à manquer "mises à jour"(c'est à dire de l'impression du contenu de la table de hachage n'est pas de s'assurer qu'il va imprimer la Carte à jour) et de l'utilisation des Api comme
CyclicBarrier
pour assurer la cohérence au sein de votre programme de cycle de vie.Collections.synchronizedMap() la méthode synchronise toutes les méthodes de la table de hachage et réduit efficacement à une structure de données où un thread peut entrer à un moment, parce qu'il verrouille chaque méthode sur une commune de la serrure.
Dans ConcurrentHashMap la synchronisation se fait un peu différemment. Plutôt que de verrouillage de chaque méthode sur la commune de verrouillage, ConcurrentHashMap utilise séparé de verrouillage pour séparer les seaux ainsi verrouillage uniquement une partie de la Carte.
Par défaut il y a 16 seaux et aussi des verrous distincts pour séparer les seaux. Donc la valeur par défaut niveau de simultanéité est de 16 ans. Cela signifie que, théoriquement, un moment donné 16 threads peuvent accéder à ConcurrentHashMap si ils sont tous allez séparer les seaux.
En plus de ce qui a été suggéré, j'aimerais afficher le code source liées à
SynchronizedMap
.De faire un
Map
thread-safe, nous pouvons utiliserCollections.synchronizedMap
instruction et l'entrée de la carte de l'instance en tant que paramètre.La mise en œuvre de
synchronizedMap
dansCollections
est comme ci-dessousComme vous pouvez le voir, l'entrée
Map
objet est enveloppé par leSynchronizedMap
objet.Nous allons creuser dans la mise en œuvre de
SynchronizedMap
,Ce
SynchronizedMap
ne peuvent être résumées comme l'ajout d'un verrou unique à la méthode principale de l'entréeMap
objet. Méthode tous gardé par le verrou ne peut pas être accédé par plusieurs threads en même temps. Cela signifie que les opérations normales commeput
etget
peut être exécuté par un seul thread en même temps pour toutes les données de laMap
objet.Il fait le
Map
objet thread-safe maintenant, mais la performance peut devenir un problème dans certains scénarios.La
ConcurrentMap
est beaucoup plus compliqué dans la mise en œuvre, nous pouvons nous référer à La construction d'une meilleure HashMap pour plus de détails. En un mot, il est mis en œuvre en tenant à la fois thread-safe et de la performance en considération.