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

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

哈希表 collections . synchronizedmap(地图) ConcurrentHashMap

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

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


当前回答

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

其他回答

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

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

以下是一些例子:

1) ConcurrentHashMap只锁定Map的一部分,而SynchronizedMap锁定整个Map。 2) ConcurrentHashMap比SynchronizedMap性能更好,扩展性更强。 3)在多读取器和单写入器的情况下,ConcurrentHashMap是最好的选择。

此文本来自Java中的ConcurrentHashMap和哈希表之间的差异

synchronizedmap()方法同步HashMap的所有方法,并有效地将其简化为每次只能进入一个线程的数据结构,因为它将每个方法锁定在一个公共锁上。

在ConcurrentHashMap中,同步的方式略有不同。ConcurrentHashMap对不同的bucket使用不同的锁,从而只锁定Map的一部分,而不是将每个方法锁定在一个公共锁上。 默认情况下,有16个桶,并且为不同的桶提供不同的锁。所以默认的并发级别是16。这意味着理论上在任何给定的时间都有16个线程可以访问ConcurrentHashMap,如果它们都要分开存储桶的话。

╔═══════════════╦═══════════════════╦═══════════════════╦═════════════════════╗
║   Property    ║     HashMap       ║    Hashtable      ║  ConcurrentHashMap  ║
╠═══════════════╬═══════════════════╬═══════════════════╩═════════════════════╣ 
║      Null     ║     allowed       ║              not allowed                ║
║  values/keys  ║                   ║                                         ║
╠═══════════════╬═══════════════════╬═════════════════════════════════════════╣
║ Thread-safety ║                   ║                                         ║
║   features    ║       no          ║                  yes                    ║
╠═══════════════╬═══════════════════╬═══════════════════╦═════════════════════╣
║     Lock      ║       not         ║ locks the whole   ║ locks the portion   ║        
║  mechanism    ║    applicable     ║       map         ║                     ║ 
╠═══════════════╬═══════════════════╩═══════════════════╬═════════════════════╣
║   Iterator    ║               fail-fast               ║ weakly consistent   ║ 
╚═══════════════╩═══════════════════════════════════════╩═════════════════════╝

关于锁定机构: Hashtable锁定对象,而ConcurrentHashMap只锁定桶。

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