简体   繁体   中英

Use Hashtable, Vector or HashMap or ArrayList in Java

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?

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 (eg 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.

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.

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

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM