并发容器与同步容器
并发容器:ConcurrentHashMap、ConcurrentSkipListMap。
同步容器:java.util.Collections中提供如下 “包装方法”。
public static <T> Collection<T> synchronizedCollection(Collection<T> c)
public static <T> List<T> synchronizedList(List<T> list)
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
public static <T> Set<T> synchronizedSet(Set<T> s)
synchronizedMap与 ConcurrentHashMap
synchronizedMap(Map)返回由指定映射支持的同步(线程安全的)映射。
synchronizedMap 在返回映射的任意 collection 视图上进行迭代时,用户必须手工在返回的映射上进行同步:
Map m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // Needn't be in synchronized block
...
synchronized(m) { // Synchronizing on m, not s !!
Iterator i = s.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}
ConcurrentHashMap的设计是线程安全的,synchronizedMap通过同步的包装器实现了线程安全。区别在于前者比后者具备更佳的可伸缩性。单线程化的ConcurrentHashMap的性能要比同步的HashMap性能稍好些,而在并发应用中,这种差距更加明显。
http://www.linkedin.com/groups/Whats-difference-between-ConcurrentHashMap-CollectionssynchronizedMap-3125654.S.60580046 写道
Collections.synchronizedMap(Map) gives you a synchronized collection that wraps the original collection in it. Before concurrent API got introduced in Java1.5, this was the way to go if you need a synchronized map. But, this was inefficient. Java 1.5 addressed this and came up a set of concurrent collections which are very efficient to use in multi-threaded environment.
ConcurrentHashMap is not a replacement for Collections.synchronizedMap(Map)! Essentially, in a highly concurrent application (large number of threads) you can go for ConcurrentHashMap as it will allow multiple threads to access different parts of the concurrent hash map simultaneously. This is because internally the hash map is split into several parts according to the concurrency level specified during the creation of ConcurrentHashMap. If the concurrency level is set as 10 for example, then 10 threads would be able to update the hashmap concurrently without blocking.
This kind of feature may not be required for not so highly concurrent application. In those cases, Collections.synchronizedMap(Map) would suffice. Two threads cannot access the Map returned by Collections.synchronizedMap(Map) simultaneously without blocking. Remember, this has not been deprecated after the introduction of ConcurrentHashMap as there are still valid usecases when this can be used.
扩展阅读
1、《java并发编程实践》性能和可伸缩性
2、探索 ConcurrentHashMap 高并发性的实现机制
3、Java 理论与实践: 构建一个更好的 HashMap