java.util.Collections class provides the following static methods to wrap a collection into a thread-safe collection:
Collection<T> synchronizedCollection(Collection<T> c)
List<T> synchronizedList(List<T> list)
Map<K,V> synchronizedMap(Map<K,V> m)
Set<S> synchronizedSet(Set<T> s)
SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)
SortedSet<T> synchronizedSortedSet(SortedSet<T> s)
The returned collection should be used instead of the wrapped collection.
When these thread-safe collection wrappers are used, the lock is obtained on them and not on the wrapped collection. Synchronization is not needed only when we perform simple operations like add, remove etc. While executing multiple operations such as put-if-absent or replace-if-found as an atomic operation you will have to use sychronization.
These synchronized collection wrappers provide fail-fast iterators. The iterators on these collections are not synchronized and should use synchronization explicitly to avoid
ConcurrentModificationException. However, the iterators on keys and values in case of
Collections.synchronizedMap i.e. iterators on
values() methods lock the thread-safe map and are not fail-fast.
These thread-safe collections allow storing null. They provide an up-to-date view of the wrapped collection. Their use is preferred over their alternative classes when there are more frequent modifications to the collection than traversal.
The Concurrency API in Java 5 provides
ConcurrentHashMap which is a synchronized map. It uses lock striping instead of locking the entire collection and hence provides better scalability in comparison with
Collections.synchronizedMap. The use of
ConcurrentHashMap should be preferred over
Collections.synchronizedMap when the read operations are more frequent than write operations on the map.
ConcurrentHashMap provides better scalabity than
Hashtable is a thread-safe map but it does not allow storing null key unlike
The Concurrency API also provides
CopyOnWriteArrayList which is a thread-safe copy of the wrapped List. Once the iterator on this list is created, any modifications to the wrapped list won’t be reflected in it. Similarly, this list never throws
ConcurrentModificationException since a new copy of the wrapped list gets created when its iterator is created. This iterator does not support any operations such as remove, add and set on it. The
UnsupportedOperationException is thrown when these methods are called it. The use of this class should be preferred over
Collections.synchronizedList when you want to use snapshot-style iterator.
The Oracle’s Java tutorial says that
Vector is slightly faster than
The Concurrency API provides
CopyOnWriteArraySet which creates a thread-safe snapshot of the wrapped Set. It can be preferred over
Collections.synchronizedSet for better scalability when you don’t want to perform mutative operations.
Java 6 has introduced
ConcurrentSkipListSet which provide a thread-safe implementation of
SortedSet respectively. The iterators of these collections do not throw
ConcurrentModificationException. Collections ordered in ascending order and their iterators are faster than the descending ones. These classes do not support insertion of null.