Pourquoi Java Vector est-il considéré comme une classe héritée, obsolète ou obsolète?
Son utilisation n'est-elle pas valable lorsque vous travaillez avec la concurrence?
Et si je ne veux pas synchroniser manuellement les objets et que je veux juste utiliser une collection thread-safe sans avoir besoin de faire de nouvelles copies du tableau sous-jacent (comme c'est le CopyOnWriteArrayList
cas), est-ce que c'est bien d'utiliser Vector
?
Qu'en est-il Stack
, qui est une sous-classe de Vector
, que dois-je utiliser à la place?
Réponses:
Vector
se synchronise sur chaque opération individuelle. Ce n'est presque jamais ce que vous voulez faire.En règle générale, vous souhaitez synchroniser toute une séquence d'opérations. La synchronisation des opérations individuelles est à la fois moins sûre (si vous parcourez un
Vector
, par exemple, vous devez toujours retirer un verrou pour éviter que quelqu'un d'autre modifie la collection en même temps, ce qui provoquerait unConcurrentModificationException
dans le thread d'itération) mais aussi plus lent ( pourquoi sortir une serrure à plusieurs reprises quand une fois suffira)?Bien sûr, il a également la surcharge de verrouillage même lorsque vous n'en avez pas besoin.
Fondamentalement, c'est une approche très imparfaite de la synchronisation dans la plupart des situations. Comme l'a souligné M. Brian Henk , vous pouvez décorer une collection en utilisant des appels tels que
Collections.synchronizedList
- le fait quiVector
combine à la fois l'implémentation de la collection "tableau redimensionné" et le bit "synchroniser chaque opération" est un autre exemple de mauvaise conception; l'approche de la décoration permet une séparation plus nette des préoccupations.Quant à un
Stack
équivalent - je regarderaisDeque
/ArrayDeque
pour commencer.la source
Le vecteur faisait partie de la version 1.0 - l'implémentation d'origine avait deux inconvénients:
1. Dénomination: les vecteurs ne sont en réalité que des listes auxquelles on peut accéder sous forme de tableaux, il aurait donc dû être appelé
ArrayList
(qui est le remplacement de Java 1.2 CollectionsVector
).2. Concurrency: Toutes les
get()
,set()
méthodes sontsynchronized
, de sorte que vous ne pouvez pas avoir un contrôle plus fin sur la synchronisation.Il n'y a pas beaucoup de différence entre
ArrayList
etVector
, mais vous devez utiliserArrayList
.À partir du document API.
la source
ArrayList
,LinkedList
etc., qui implémentent tous l'interfaceList
, donc si vous voulez utiliser lesList
méthodes sans avoir à connaître l'implémentation sous-jacente, vous pouvez simplement prendre unList
comme paramètre pour les méthodes, etc. Il en va de même pour les implémenteurs deMap
etc. Pendant ce temps, C ++ a unestd::array
classe, qui n'est qu'un remplacement basé sur un modèle pour les tableaux de longueur statique de style C.Outre les réponses déjà énoncées sur l'utilisation de Vector, Vector a également un tas de méthodes autour de l'énumération et de la récupération des éléments qui sont différentes de l'interface List, et les développeurs (en particulier ceux qui ont appris Java avant 1.2) peuvent avoir tendance à les utiliser s'ils sont dans le code. Bien que les énumérations soient plus rapides, elles ne vérifient pas si la collection a été modifiée pendant l'itération, ce qui peut provoquer des problèmes, et étant donné que Vector peut être choisi pour sa synchronisation - avec l'accès associé à partir de plusieurs threads, cela en fait un problème particulièrement pernicieux. L'utilisation de ces méthodes couple également beaucoup de code à Vector, de sorte qu'il ne sera pas facile de le remplacer par une implémentation de List différente.
la source
Vous pouvez utiliser la méthode synchronizedCollection / List dans
java.util.Collection
pour obtenir une collection thread-safe à partir d'une collection non thread-safe.la source
java.util.Stack
hérite des frais généraux de synchronisation dejava.util.Vector
, ce qui n'est généralement pas justifié.Cependant, il hérite de bien plus que cela. Le fait que
java.util.Stack extends java.util.Vector
c'est une erreur dans la conception orientée objet. Les puristes noteront qu'il propose également de nombreuses méthodes au-delà des opérations traditionnellement associées à une pile (à savoir: push, pop, peek, size). Il est également possible de le fairesearch
,elementAt
,setElementAt
,remove
, et bien d' autres opérations d'accès aléatoire. C'est essentiellement à l'utilisateur de s'abstenir d'utiliser les opérations hors pile deStack
.Pour ces raisons de performances et de conception OOP, JavaDoc for
java.util.Stack
recommandeArrayDeque
comme remplacement naturel. (Un deque est plus qu'une pile, mais au moins il se limite à manipuler les deux extrémités, plutôt qu'à offrir un accès aléatoire à tout.)la source