2009-01-17 5 views
12

Un meme qui est stressé par le développement Java est toujours utiliser ArrayList sur Vector. Le vecteur est obsolète. C'est peut-être vrai, mais Vector et Hashtable ont l'avantage d'être synchronisés.Utiliser Hashtable, Vector ou HashMap ou ArrayList dans Java

Je travaille avec une application orientée fortement concurrente, ne serait-il pas avantageux d'utiliser des objets synchronisés comme Vector? Il semble qu'ils ont leur place?

+0

Le vecteur n'a pas encore été déprécié. – Champ

+0

La dernière version de Java 6 avec Netbeans prétend que Vector est obsolète ... Il doit avoir été annoncé quelque part il y a quelque temps, parce que j'ai des notes datant de quelques mois sur le besoin de trouver un remplacement et les problèmes avec certains non classes -deprecated encore en ont besoin. –

Répondre

17

Le problème avec Vector et Hashtable est qu'ils sont seulement synchronisés localement. Ils ne se casseront pas (comme dans les données corrompues) dans une application simultanée, cependant, en raison de la synchronisation locale (par exemple, get est synchronisé, mais seulement jusqu'à obtenir des retours), vous voudrez effectuer votre propre synchronisation de toute façon comme itération sur le contenu. Maintenant, même votre méthode put nécessite une synchronisation supplémentaire pour coopérer avec la synchronisation d'itération et vous vous retrouvez avec une situation où votre Hashtable/Vector est doublement synchronisé.

+0

Exactement ce qui est incorrect? – falstro

+0

J'ai supprimé mon commentaire par erreur. Vous êtes incorrect que put() nécessite une synchronisation supplémentaire; l'itérateur() ne ferait que se synchroniser sur le vecteur lui-même, qui se mute avec toute la synchronisation dans le vecteur. Dans ce cas, ils sont identiques à Collections.synchronizedList(). –

+0

Si vous utilisez votre itérateur dans une boucle for, le contenu de la boucle ne sera pas synchronisé et votre itérateur lèvera probablement une exception de modification simultanée si quelqu'un utilise la valeur 'next'. Par conséquent, vous avez besoin d'une synchronisation supplémentaire (il y a bien sûr d'autres options). – falstro

13

Si vous avez besoin d'ArrayList ou de HashMap synchronisés, vous pouvez les enrouler. Personnellement, je trouve que les méthodes "synchronisées" dans ces collections ne sont pas très utiles dans le code thread lourd. Il y a quelques nouvelles collections qui aident beaucoup plus, mais surtout je me retrouve à faire mes propres synchroniser les objets et à les synchroniser autour d'eux, ou en utilisant les nouveaux verrous dans java.util.concurrent

8

La synchronisation a sa place, mais ce n'est pas le seule différence entre Vector et ArrayList. Vector augmente sa matrice de stockage interne d'une quantité fixe chaque fois qu'elle dépasse sa capacité, tandis que ArrayList le fait augmenter d'un facteur fixe, ce qui est généralement une meilleure approche (puisqu'il donne amortized cost de O (1) pour ajouter un élément).

Notez également que Collections.synchronizedList() peut être utilisé pour créer une vue synchronisée sur une mise en œuvre List, de sorte que vous ne devez pas être lié aux caractéristiques de Vector (vous voudrez peut-être un synchronisé LinkedList par exemple).

+2

Pas tout à fait. Si vous ne définissez pas l'attribut capacityIncrement sur un vecteur, il doublera par défaut sa taille si une capacité supplémentaire est nécessaire. –

+0

Il semble que je dois avoir mal se souvient de cela! –

0

Il me semble que la seule fois que vous aurez besoin de la collection elle-même pour être sûr de fil sont:

  • Si la collection est visible de l'extérieur de la classe (portée publique ou par défaut)
  • Si vous retournez une poignée à la collecte d'une méthode
  • Si la collection est un membre statique de votre classe

Tous ces éléments sont probablement une mauvaise idées du design.

Une meilleure approche serait de rendre la collection elle-même privée ou protégée, et y accéder via des méthodes synchronisées. Dans le cas du membre statique, si vous aviez besoin de le faire, un Singleton serait une meilleure solution.

17

ConcurrentHashMap est way faster que Hashtable.C'est concurrent, pas seulement synchronisé. Il admet plusieurs lecteurs/écrivains à la fois.

Cependant, il n'existe aucune liste de type 'concurrent'. Selon vos besoins, CopyOnWriteArrayList peut ou peut ne pas être ce dont vous avez besoin.