Pregunta ¿Por qué la clase Java Vector (y Stack) se considera obsoleta o obsoleta?


¿Por qué Java Vector se considera una clase heredada, obsoleta o desaprobada?

¿No es válido su uso cuando se trabaja con concurrencia?

Y si no quiero sincronizar manualmente objetos y solo quiero usar una colección segura para hilos sin necesidad de hacer copias recientes de la matriz subyacente (como CopyOnWriteArrayList hace), entonces está bien usar Vector?

Qué pasa Stack, que es una subclase de Vector, ¿qué debería usar en lugar de eso?


612
2017-09-06 18:04


origen


Respuestas:


Vector sincroniza en cada operación individual. Eso casi nunca es lo que quieres hacer.

En general, quiere sincronizar un secuencia completa de operaciones. La sincronización de operaciones individuales es menos segura (si itera sobre un Vector, por ejemplo, aún necesita sacar un candado para evitar que alguien más cambie la colección al mismo tiempo, lo que causaría un ConcurrentModificationException en el hilo de iteración) pero también más lento (¿por qué sacar un bloqueo repetidamente cuando una vez será suficiente)?

Por supuesto, también tiene la sobrecarga de bloqueo, incluso cuando no es necesario.

Básicamente, es un enfoque muy defectuoso para la sincronización en la mayoría de las situaciones. Como Sr. Brian Henk señaló, puede decorar una colección utilizando las llamadas como Collections.synchronizedList - el hecho de que Vector combina la implementación de la colección "resize array" con el bit "synchronize every operation" es otro ejemplo de diseño deficiente; el enfoque de decoración ofrece una separación más clara de las preocupaciones.

En cuanto a un Stack equivalente - miraría Deque/ArrayDeque para empezar.


601
2017-09-06 18:07



Vector fue parte de 1.0 - la implementación original tenía dos inconvenientes:

1. Denominación: los vectores son realmente solo listas a las que se puede acceder como matrices, por lo que debería haberse llamado ArrayList (que es el reemplazo de colecciones Java 1.2 para Vector)

2. Concurrencia: Toda la get(), set() los métodos son synchronized, por lo que no puede tener un control detallado sobre la sincronización.

No hay mucha diferencia entre ArrayList y Vector, pero deberías usar ArrayList.

De la API doc.

A partir de la plataforma Java 2 v1.2, esto   clase fue adaptada para implementar la   Interfaz de lista, por lo que es un miembro de   el marco de colecciones de Java. diferente a   las nuevas implementaciones de colecciones,   Vector está sincronizado.


74
2017-09-06 18:12



Además de las respuestas ya establecidas sobre el uso de Vector, Vector también tiene un montón de métodos alrededor de enumeración y recuperación de elementos que son diferentes a la interfaz de Lista, y los desarrolladores (especialmente aquellos que aprendieron Java antes 1.2) pueden tender a usarlos si están en el código. Aunque las enumeraciones son más rápidas, no comprueban si la colección se modificó durante la iteración, lo que puede causar problemas, y dado que se podría elegir Vector para su sincronización, con el acceso de múltiples hilos, esto lo convierte en un problema particularmente pernicioso. El uso de estos métodos también acopla una gran cantidad de código a Vector, de modo que no será fácil reemplazarlo con una implementación de Lista diferente.


40
2017-09-06 20:53



Puedes usar el Colección sincronizada / Lista método en java.util.Collection para obtener una colección segura de subprocesos de una que no sea segura para subprocesos.


14
2017-09-06 18:07



java.util.Stack hereda la sobrecarga de sincronización de java.util.Vector, que usualmente no está justificado.

Sin embargo, hereda mucho más que eso. El hecho de que java.util.Stack extends java.util.Vector es un error en el diseño orientado a objetos. Los puristas notarán que también ofrece muchos métodos más allá de las operaciones tradicionalmente asociadas a una pila (a saber: push, pop, peek, size). También es posible hacer search, elementAt, setElementAt, removey muchas otras operaciones de acceso aleatorio. Básicamente depende del usuario abstenerse de utilizar las operaciones que no son de pila de Stack.

Por estos motivos de diseño de rendimiento y OOP, JavaDoc para java.util.Stack recomienda ArrayDeque como el reemplazo natural. (Un deque es más que una pila, pero al menos está restringido a la manipulación de los dos extremos, en lugar de ofrecer acceso aleatorio a todo).


4
2018-02-12 21:04