Différence entre Hashtable et Collections.synchronizedMap(HashMap))
autant que je sache, java.util.Hashtable
synchronise toutes les méthodes de l'interface java.util.Map
, tandis que Collections.synchronizedMap(hash_map)
renvoie un objet wrapper contenant des méthodes synchronisées déléguant les appels à la réelle hash_map
(corrigez-moi si je me trompe).
j'ai deux questions:
-
quelle différence fait - il faire pour synchroniser chaque méthode et d'avoir une classe wrapper? Quels sont les scénarios de choisir l'un plutôt que l'autre?
-
Ce qui se passe quand nous ne
Collections.synchronizedMap(hash_table)
? Sera-t-elle égale à simplement utiliser unjava.util.Hashtable
normal ?
6 réponses
Voici les réponses que j'ai obtenues d'un peu de recherche (avec un peu de chance correcte):
-
" les deux fournissent le même degré de synchronisation. Si vous deviez emballer
Hashtable
dans les Collections.synchronisé vous auriez le même degré, mais avec une autre couche redondante, de synchronisation. -
la principale différence entre
Hashtable
etCollections.synchronizedMap(HashMap)
existe davantage au niveau de L'API. Parce queHashtable
fait partie du code d'héritage de Java, vous verrez que l'APIHashtable
est améliorée pour implémenter l'interfaceMap
, pour devenir une partie du cadre de collections de Java. Cela signifie que si vous deviez envelopperHashtable
parCollections.synchronizedMap()
, l'API duHashtable
serait limitée à L'APIMap
. Donc si L'API deHashtable
est incluse dans votre définition de behavior , alors il est évidemment modifié/limité.
une autre différence que je peux trouver à la mise en œuvre des deux classes est la suivante:
• la classe Hashtable
a toutes ses méthodes synchronisées i.e. le verrouillage est fait au niveau de la méthode et donc on peut dire que le mutex est toujours à l'objet Hashtable
( this
) niveau.
• la méthode Collections.synchronizedMap(Map)
renvoie une instance de SynchronizedMap
qui est une classe intérieure de la classe Collections
. Cette classe a toutes ses méthodes dans un bloc Synchronized
avec un mutex. La différence réside dans le mutex ici. La classe intérieure SynchronizedMap
a deux constructeurs, l'un qui ne prend que Map
comme argument et l'autre qui prend un Map
et un Object
(mutex) comme argument. Par défaut si on utilise le premier constructeur de passer seulement un Map
, this
est utilisé comme mutex. Cependant, l' developer est autorisé à passer un autre objet de mutex comme second argument par lequel la serrure sur les méthodes Map
ne serait que sur ce Object
et donc moins restrictive que Hashtable
.
* par conséquent, Hashtable
utilise la synchronisation du niveau de la méthode mais Collections.synchronizedMap(Map)
fournit une flexibilité pour le verrouillage du développeur sur mutex fourni avec Synchronized
bloc.
la première classe de collection associative à apparaître dans la classe Java bibliothèque était Hashtable, qui faisait partie de JDK 1.0. Hashtable fourni un facile à utiliser, thread-safe, associatif carte de capacité, et il a été certainement pratique. Cependant, la sécurité de fil est venu à un prix -- toutes les méthodes de Hashtable ont été synchronisées. À l'époque, uncontended la synchronisation avait un coût de rendement mesurable. Le successeur de Hashtable, HashMap, qui est apparu dans collection cadre dans JDK 1.2, abordé thread-sécurité en fournissant un classe de base non synchronisée et enveloppe synchronisée, Collection.synchronizedMap. Séparation de la fonctionnalité de base les Collections thread-safety.synchronizedMap permet aux utilisateurs qui en ont besoin synchronisation pour l'avoir, mais les utilisateurs qui n'en ont pas besoin n'ont pas à payer pour cela.
l'approche simple de la synchronisation prise à la fois par Hashtable et synchronizedMap -- synchroniser chaque méthode sur le Hashtable ou le objet synchronisé d'enveloppement de carte -- a deux défauts principaux. Il est un obstacle à l'évolutivité, car un seul thread peut accéder à la table de hachage à la fois. Dans le même temps, il est insuffisant pour assurer la sécurité du vrai fil, en ce que de nombreuses opérations de composés communs nécessite encore une synchronisation supplémentaire. Alors que les opérations simples telles comme get() et put () peuvent être complétés en toute sécurité sans la synchronisation, il y a plusieurs séquences d'opérations, comme l'itération ou mettez-si absent, qui nécessitent encore externe synchronisation pour éviter les courses de données.
le lien suivant est la source et donne plus d'information: classes de Collections concurrentes
la différence n'est pas seulement évidente au niveau de L'API et il y a de nombreuses subtilités au niveau de la mise en œuvre. Par exemple, Hashtable
ne fait pas de sport HashMap
's recalcul avancé des hashcodes de touches fournies qui réduit les collisions de hachage. D'un autre côté, Hashtable#hashCode()
évite la récursion infinie pour les hashtables auto-référentiels pour permettre à"certaines applets 1.1-era avec des tables de hachage auto-référentielles de fonctionner".
En général, cependant, on ne devrait pas compter sur Hashtable
recevoir toutes améliorations ou raffinements supplémentaires au-delà de l'exactitude de base et de la compatibilité en amont. Il est considéré comme une relique du profond passé de Java.
au risque d'affirmer l'évidence (ou d'être tout à fait erroné) n'est pas la différence que
l'enveloppe de synchronisation ajoute la synchronisation automatique (filet de sécurité) pour une collection arbitraire
http://docs.oracle.com/javase/tutorial/collections/implementations/wrapper.html et continue à dire
une collection créée de cette façon est chaque peu comme fil-safe comme un collecte normalement synchronisée, comme un vecteur.
comme Vous pouvez le voir ce fil de discussion pour les questions relatives à HashMaps et de la concurrence - Hashmap problème de concurrence (ou vous êtes peut-être très conscients de leur déjà). Un bon exemple est:
les conditions que vous décrivez ne seront pas remplies par HashMap. Depuis le processus de mise à jour d'une carte n'est pas atomique, vous pouvez la rencontre de la carte dans un état non valide. Plusieurs écritures peuvent le laisser dans un corrompu état. Competienthashmap (1.5 ou plus tard) fait ce que vous voulez.
https://stackoverflow.com/a/1003071/201648
je suppose qu'en termes de" quand devrais-je utiliser ceci " j'aurais tendance à utiliser la collection syncronisée où la concurrence est requise, sinon vous pourriez créer plus de travail pour vous-même (voir ci-dessous).
En termes de modifier le comportement
Si explicite itérateur est utilisé, la méthode de l'itérateur doit être appelée à partir de l'intérieur de la synchronisation de bloc. Le défaut de suivre ces conseils peuvent résultat de tout comportement non déterministe
il y a plus de conséquences d'utiliser la synchronisation donnée sur le lien (Oracle) fourni.
un autre point de différence à noter est que HashTable ne permet pas les clés nulles ou les valeurs nulles tandis que HashMap permet une clé null et n'importe quel nombre de valeurs nulles. Puisque synchronizedMap est enveloppé par HashMap, son comportement en ce qui concerne les clés nulles et les valeurs est le même que HashMap.