Pourquoi la classe Java Vector (et Stack) est-elle considérée comme obsolète ou obsolète?


Pourquoi Java Vector est-il considéré comme une classe héritée, obsolète ou obsolète?

Son utilisation n'est-elle pas valide 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 le fait CopyOnWriteArrayList), est-ce bien d'utiliser Vector?

Qu'en est-il de Stack, qui est une sous-classe de Vector, que dois-je utiliser à sa place?

Author: Patrick Parker, 2009-09-06

5 answers

Vector synchronise sur chaque opération. C'est presque jamais ce que vous voulez faire.

Généralement, vous souhaitez synchroniser une séquence entière d'opérations. La synchronisation des opérations individuelles est à la fois moins sûre (si vous itérez sur un Vector, par exemple, vous devez toujours retirer un verrou pour éviter que quelqu'un d'autre ne change la collection en même temps, ce qui provoquerait un ConcurrentModificationException dans le thread d'itération) mais aussi plus lent (pourquoi retirer un verrou à plusieurs reprises quand une assez)?

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 M. Brian Henk l'a souligné, vous pouvez décorer une collection en utilisant les appels tels que Collections.synchronizedList - le fait que Vector combine à la fois l'implémentation de la collection "redimensionnée" avec le bit "synchroniser chaque opération" est un autre exemple de mauvaise conception; l'approche de décoration donne plus propre séparation des préoccupations.

Pour un Stack équivalent - je regarderais Deque/ArrayDeque pour commencer avec.

 607
Author: Jon Skeet, 2015-09-26 12:05:27

Vector faisait partie de 1.0 -- l'implémentation originale avait deux inconvénients:

1. Naming: les vecteurs ne sont en fait que des listes accessibles en tant que tableaux, il aurait donc dû être appelé ArrayList (qui est le remplacement des collections Java 1.2 pour Vector).

2. Concurrence: Tous les get(), set() les méthodes sont synchronized, vous ne pouvez donc pas avoir de contrôle précis sur la synchronisation.

Il n'y a pas beaucoup de différence entre ArrayList et Vector, mais vous devez utiliser ArrayList.

Du document API.

À partir de la plate-forme Java 2 v1. 2, cette classe a été modernisée pour mettre en œuvre le Interface de liste, ce qui en fait un membre de le cadre des collections Java. Contrairement les nouvelles implémentations de collection, Le vecteur est synchronisé.

 75
Author: Justin, 2017-09-24 07:21:24

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 d'éléments qui sont différentes de l'interface de liste, 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 causer des problèmes, et étant donné que Vector peut être choisi pour sa syncronisation-avec le préposé accès à partir de plusieurs threads, cela en fait un problème particulièrement pernicieux. L'utilisation de ces méthodes couple également beaucoup de code au vecteur, de sorte qu'il ne sera pas facile de le remplacer par une implémentation de liste différente.

 40
Author: Yishai, 2009-09-06 20:53:26

Vous pouvez utiliser la méthode synchronizedCollection/List sur java.util.Collection pour obtenir une collection thread safe à partir d'une collection non thread safe.

 15
Author: Brian Henk, 2017-09-24 07:19:43

java.util.Stack hérite de la surcharge de synchronisation de java.util.Vector, ce qui n'est généralement pas justifié.

Il hérite cependant beaucoup plus que cela. Le fait que java.util.Stack extends java.util.Vector est une erreur dans la conception orientée objet. Les puristes noteront qu'il offre également beaucoup de méthodes au-delà des opérations traditionnellement associées à une pile (à savoir: push, pop, peek, size). Il est également possible de faire search, elementAt, setElementAt, remove, et beaucoup d'autres opérations d'accès aléatoire. C'est fondamentalement à l'utilisateur de s'abstenir en utilisant les opérations non-pile de Stack.

Pour ces performances et de la programmation orientée objet raisons de conception, la JavaDoc pour java.util.Stack recommande ArrayDeque comme le remplacement naturel. (Un deque est plus qu'une pile, mais au moins il se limite à manipuler les deux extrémités, plutôt que d'offrir un accès aléatoire à tout.)

 4
Author: 200_success, 2016-02-12 21:04:52