views:

9749

answers:

4

Why Java Vector is considered a legacy class, obsolete or deprecated?

Its use isn't valid when working with concurrency?

And if I don't want to manually synchronize objects and just want to use a thread-safe collection without needing to make fresh copies of the underlying array (as CopyOnWriteArrayList does), then it is fine to use Vector?

What about Stack, which is a subclass of Vector, what should I use instead of it?

+1  A: 

Yiu can use the synchronizedCollection/List method on java.util.Collection to get a thread safe collection from a non-thread safe one. http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html#synchronizedCollection%28java.util.Collection)

Brian Henk
why this is better than vector?
fjsj
As Jon mentioned, Vector will not perform as well, and this method allows you to choose when its a good idea to do the synchronization.Its totally a design issue. You should use ArrayList over Vector because you should default to non-synchronized access.
Brian Henk
+25  A: 

Vector synchronizes on each individual operation. That's almost never what you want to do.

Generally you want to synchronize a whole sequence of operations. Synchronizing individual operations is both less safe (if you iterate over a Vector, for instance, you still need to take out a lock to avoid anyone else changing the collection at the same time) but also slower (why take out a lock repeatedly when once will be enough)?

Of course, it also has the overhead of locking even when you don't need to.

Basically, it's a very flawed approach to synchronization in most situations. As MrSpandex pointed out, you can decorate a collection using the calls such as Collections.synchronizedList - the fact that Vector combines both the "resized array" collection implementation with the "synchronize every operation" bit is another example of poor design; the decoration approach gives cleaner separation of concerns.

As for a Stack equivalent - I'd look at Deque/ArrayDeque to start with.

Jon Skeet
+1 I really like your answer, especially the first part. Thanks.
KLE
"Generally you want to synchronize a whole sequence of operations." - That is the point! Thanks!
fjsj
+5  A: 

Vector was part of 1.0 -- the original implementation had two drawbacks: 1) Naming: vectors are really just lists which can be accessed as arrays, so it should have been called ArrayList (which is the 1.5 Collections replacement for Vector). 2) Concurrency: All of the get() set() methods are synchronized, so you can't have fine grained control over synchronization.

There is not much difference between ArrayList and Vector, but you should use ArrayList.

From the API doc.

As of the Java 2 platform v1.2, this class was retrofitted to implement the List interface, making it a member of the Java Collections Framework. Unlike the new collection implementations, Vector is synchronized.

Justin
+4  A: 

Besides the already stated answers about using Vector, Vector also has a bunch of methods around enumeration and element retrieval which are different than the List interface, and developers (especially those who learned Java before 1.2) can tend to use them if they are in the code. Although Enumerations are faster, they don't check if the collection was modified during iteration, which can cause issues, and given that Vector might be chosen for its syncronization - with the attendant access from multiple threads, this makes it a particularly pernicious problem. Usage of these methods also couples a lot of code to Vector, such that it won't be easy to replace it with a different List implementation.

Yishai
+1 for saying "pernicious"
skaffman