我有一个映射,这是由几个线程并发修改。
在Java API中似乎有三种不同的同步Map实现:
哈希表
collections . synchronizedmap(地图)
ConcurrentHashMap
根据我的理解,Hashtable是一个旧的实现(扩展了过时的Dictionary类),后来为了适应Map接口而进行了调整。虽然它是同步的,但它似乎有严重的可伸缩性问题,不推荐用于新项目。
那另外两个呢?Collections.synchronizedMap(Map)和ConcurrentHashMaps返回的Map之间有什么区别?哪一种适合哪种情况?
两者之间的主要区别是ConcurrentHashMap将只锁定正在更新的部分数据,而其他部分数据可以由其他线程访问。但是,Collections.synchronizedMap()将在更新时锁定所有数据,其他线程只能在释放锁时访问数据。如果更新操作较多,读操作相对较少,则选择ConcurrentHashMap。
Also one other difference is that ConcurrentHashMap will not preserve the order of elements in the Map passed in. It is similar to HashMap when storing data. There is no guarantee that the element order is preserved. While Collections.synchronizedMap() will preserve the elements order of the Map passed in. For example, if you pass a TreeMap to ConcurrentHashMap, the elements order in the ConcurrentHashMap may not be the same as the order in the TreeMap, but Collections.synchronizedMap() will preserve the order.
此外,ConcurrentHashMap可以保证当一个线程更新映射而另一个线程遍历从映射中获得的迭代器时,不会抛出ConcurrentModificationException。但是,Collections.synchronizedMap()在此上不被保证。
有一篇文章展示了这两者的区别,还有ConcurrentSkipListMap。
ConcurrentHashMap
ConcurrentHashMap for performance-critical applications where there are far more write operations than there are read operations.
It is thread safe without synchronizing the whole map.
Reads can happen very fast while write is done with a lock.
There is no locking at the object level.
The locking is at a much finer granularity at a hashmap bucket level.
ConcurrentHashMap doesn’t throw a ConcurrentModificationException if one thread tries to modify it while another is iterating over it.
ConcurrentHashMap uses multitude of locks.
read operations are non-blocking, whereas write operations take a lock on a particular segment or bucket.
SynchronizedHashMap
对象级同步。
每个读/写操作都需要获得锁。
锁定整个集合是一种性能开销。
这实际上只允许一个线程访问整个映射,并阻塞了所有其他线程。
这可能会引起争论。
SynchronizedHashMap返回迭代器,它在并发修改时快速失败。
Collection.synchronizedMap ()
Collections实用程序类提供了操作集合并返回包装集合的多态算法。它的synchronizedMap()方法提供了线程安全的功能。
当数据一致性至关重要时,我们需要使用Collections.synchronizedMap()。
源