我有一个映射,这是由几个线程并发修改。

在Java API中似乎有三种不同的同步Map实现:

哈希表 collections . synchronizedmap(地图) ConcurrentHashMap

根据我的理解,Hashtable是一个旧的实现(扩展了过时的Dictionary类),后来为了适应Map接口而进行了调整。虽然它是同步的,但它似乎有严重的可伸缩性问题,不推荐用于新项目。

那另外两个呢?Collections.synchronizedMap(Map)和ConcurrentHashMaps返回的Map之间有什么区别?哪一种适合哪种情况?


当前回答

一般来说,如果你想使用ConcurrentHashMap,确保你已经准备好错过“更新”(即打印HashMap的内容并不能确保它会打印最新的Map),并使用CyclicBarrier等api来确保程序生命周期的一致性。

其他回答

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()。

一般来说,如果你想使用ConcurrentHashMap,确保你已经准备好错过“更新”(即打印HashMap的内容并不能确保它会打印最新的Map),并使用CyclicBarrier等api来确保程序生命周期的一致性。

如果数据一致性非常重要-使用Hashtable或Collections.synchronizedMap(Map)。 如果速度/性能非常重要,数据更新可能会受到影响-使用ConcurrentHashMap。

ConcurrentHashMap针对并发访问进行了优化。

访问不锁定整个映射,而是使用更细粒度的策略,这提高了可伸缩性。还有专门针对并发访问的功能增强,例如并发迭代器。

根据您的需要,使用ConcurrentHashMap。它允许从多个线程并发修改Map,而不需要阻塞它们。synchronizedmap (map)创建了一个阻塞map,这会降低性能,但确保了一致性(如果使用得当)。

如果您需要确保数据的一致性,并且每个线程需要有一个最新的映射视图,则使用第二个选项。如果性能非常关键,并且每个线程只向映射中插入数据,读取频率较低,则使用第一种方法。