14

One meme that gets stressed with Java development is always use ArrayList over Vector. Vector is deprecated. That may be true, but Vector and Hashtable have the advantage that they are synchronized.

I am working with a heavily concurrent oriented application, wouldn't it benefit to use objects that are synchronized like Vector? It seems that they have their place?

2
  • Vector has not been deprecated yet. Commented Sep 12, 2010 at 8:44
  • The latest rev of Java 6 with Netbeans claims that Vector is deprecated... It must have been announced somewhere else awhile ago, because I have notes going back a few months about needing to find a replacement for it and the problems with some non-deprecated classes still needing it. Commented Sep 23, 2010 at 11:32

6 Answers 6

17

The problem with Vector and Hashtable is that they're only locally synchronized. They won't break (as in corrupt data) in a concurrent application, however, due to the local synchronization (e.g. get is synchronized, but only until get returns), you'll be wanting to perform your own synchronization anyway for situations such as iteration over the content. Now, even your put-method needs some extra synchronization to cooperate with the iteration synchronization and you end up with a situation where your Hashtable/Vector is doubly synchronized.

Sign up to request clarification or add additional context in comments.

4 Comments

Deleted my comment by mistake. You are incorrect that put() needs added synchronization; the iterator() would just sync on the vector itself, which mutexes with all synchronization within vector. In this they are identical to a Collections.synchronizedList().
If you use your iterator in a for-loop, the for-loop content would not be synchronized and your iterator would probably throw a concurrent modification exception if someone use put between 'next's. Hence, you need extra synchronization (there are other options as well of course).
Yes, a synchronized around the loop, as documented in the Collections doc. But you don't need added synchronization around your put's and other accesses to "cooperate" with the iteration, as you so stipulated.
Ah, yes I see what you mean, you are of course correct. I guess I was a little fast in expressing the fact that you're likely to want a separate synchronization scheme, not related to a single array/map, and as such the intrinsic synchronization will be pure overhead.
17

ConcurrentHashMap is way faster than Hashtable. It's concurrent, not just synchronized. It admits multiple readers/writers at once.

There is no such 'concurrent' array list though. Depending on your needs, CopyOnWriteArrayList may or may not be what you need.

Comments

13

If you need synchronized ArrayList or HashMap, you can wrap them.

List list = Collections.synchronizedList(new ArrayList(...));
Map m = Collections.synchronizedMap(new HashMap(...));

Personally I find the "synchronized" methods in these collections not very useful in heavy threaded code. There are some newer collections that help a lot more, but mostly I find myself making my own synchronize objects and synchronizing around them, or using the new locks in java.util.concurrent

Comments

9

Synchronization has its place, but that's not the only difference between Vector and ArrayList. Vector grows its internal storage array by a fixed amount every time it exceeds its capacity, while ArrayList grows it by a fixed factor, which is usually a much better approach (since it gives an amortized cost of O(1) for appending an item).

Also note that Collections.synchronizedList() can be used to create a synchronized view on any List implementation, so you don't have to be bound to the characteristics of Vector (you might want a synchronized LinkedList for example).

2 Comments

Not quite. If you don't set the capacityIncrement on a Vector, it will default to doubling its size when additional capacity is needed.
It seems I must have mis-remembered this!
3

You can use static Collections methods to convert a List or Map into a synchronized version: http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html#synchronizedList(java.util.List)

In general you normally need to lock for more that an individual call to the list or map.

Comments

0

It seems to me that the only times you'd need the Collection itself to be thread safe are:

  • If the Collection is visible from outside the class (Public or default scope)
  • If you're returning a handle to the collection from a method
  • If the collection is a static member of your class

All of those are probably a bad ideas design-wise.

A better approach would be to make the collection itself Private or Protected, and access it via synchronized methods. In the case of the static member, if you had a need to do that, a Singleton would be a better way to go.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.