¿Por qué se considera Java Vector una clase heredada, obsoleta o en desuso?
¿No es válido su uso cuando se trabaja con concurrencia?
Y si no quiero sincronizar manualmente los objetos y solo quiero usar una colección segura para subprocesos sin necesidad de hacer copias nuevas de la matriz subyacente (como lo CopyOnWriteArrayList
hace), ¿está bien usarla Vector
?
¿Qué pasa Stack
, que es una subclase de Vector
, qué debo usar en lugar de eso?
Respuestas:
Vector
se sincroniza en cada operación individual. Eso casi nunca es lo que quieres hacer.Generalmente desea sincronizar una secuencia completa de operaciones. Sincronizar operaciones individuales es menos seguro (si itera sobre
Vector
, por ejemplo, aún necesita quitar un bloqueo para evitar que alguien más cambie la colección al mismo tiempo, lo que provocaría unConcurrentModificationException
en el hilo iterativo) pero también más lento ( ¿Por qué sacar una cerradura 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 señaló el Sr. Brian Henk , puede decorar una colección usando las llamadas tales como
Collections.synchronizedList
: el hecho de queVector
combina la implementación de la colección "matriz redimensionada" con el bit "sincronizar cada operación" es otro ejemplo de diseño deficiente; El enfoque de la decoración da una separación más limpia de las preocupaciones.En cuanto a un
Stack
equivalente, miraríaDeque
/ArrayDeque
para comenzar.fuente
Vector era parte de 1.0: la implementación original tenía dos inconvenientes:
1. Naming: los vectores son realmente solo listas a las que se puede acceder como matrices, por lo que deberían haberse llamado
ArrayList
(que es el reemplazo de las colecciones de Java 1.2Vector
).2. Concurrencia: Todo el
get()
,set()
métodos sonsynchronized
, por lo que no puede haber grano fino control sobre la sincronización.No hay mucha diferencia entre
ArrayList
yVector
, pero debes usarloArrayList
.De la API doc.
fuente
ArrayList
,LinkedList
, etc., todos los cuales implementan la interfazList
, por lo que si desea utilizar losList
métodos sin necesidad de saber lo que la aplicación subyacente realidad es que sólo puede tomar unList
como un parámetro a los métodos, etc. Lo mismo se aplica para los ejecutores deMap
y así. Mientras tanto, C ++ tiene unastd::array
clase, que es solo un reemplazo basado en plantillas para matrices de longitud estática de estilo C.Además de las respuestas ya mencionadas sobre el uso de Vector, Vector también tiene un montón de métodos 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 de 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 Vector podría elegirse para su sincronización, con el acceso de múltiples subprocesos, esto lo convierte en un problema particularmente pernicioso. El uso de estos métodos también combina mucho código con Vector, de modo que no será fácil reemplazarlo con una implementación de Lista diferente.
fuente
Puede usar el método synchronizedCollection / List
java.util.Collection
para obtener una colección segura para subprocesos de una colección no segura para subprocesos.fuente
java.util.Stack
hereda la sobrecarga de sincronización dejava.util.Vector
, que generalmente no está justificada.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 con una pila (a saber: push, pop, peek, size). También es posible hacersearch
,elementAt
,setElementAt
,remove
, y muchas otras operaciones de acceso aleatorio. Básicamente, depende del usuario abstenerse de usar las operaciones no apiladas deStack
.Por estas razones de rendimiento y diseño de OOP, JavaDoc para
java.util.Stack
recomiendaArrayDeque
como el reemplazo natural. (Una deque es más que una pila, pero al menos está restringida a manipular los dos extremos, en lugar de ofrecer acceso aleatorio a todo).fuente