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:

  1. 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?

  2. Ce qui se passe quand nous ne Collections.synchronizedMap(hash_table) ? Sera-t-elle égale à simplement utiliser un java.util.Hashtable normal ?

42
demandé sur Pacerier 2012-01-16 08:10:25

6 réponses

Voici les réponses que j'ai obtenues d'un peu de recherche (avec un peu de chance correcte):

  1. " 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.

  2. la principale différence entre Hashtable et Collections.synchronizedMap(HashMap) existe davantage au niveau de L'API. Parce que Hashtable fait partie du code d'héritage de Java, vous verrez que l'API Hashtable est améliorée pour implémenter l'interface Map , pour devenir une partie du cadre de collections de Java. Cela signifie que si vous deviez envelopper Hashtable par Collections.synchronizedMap() , l'API du Hashtable serait limitée à L'API Map . Donc si L'API de Hashtable est incluse dans votre définition de behavior , alors il est évidemment modifié/limité.

14
répondu Nadir Muzaffar 2017-07-14 17:33:44

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.

56
répondu mankadnandan 2014-02-28 01:29:48

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

4
répondu bchetty 2013-08-19 09:14:32

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.

3
répondu Marko Topolnik 2012-12-12 12:00:17

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.

1
répondu Aaron Newton 2017-05-23 11:47:29

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.

1
répondu Rahul Jangra 2018-04-14 03:47:33