tags:

views:

5937

answers:

6

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?

+13  A: 

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.

roe
Exactly what is incorrect?
roe
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().
Software Monkey
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).
roe
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.
Software Monkey
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.
roe
+8  A: 

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

Paul Tomblin
+5  A: 

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).

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

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.

Douglas Leeder
A: 

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.

Clayton
+11  A: 

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.

Peter Štibraný