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

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

哈希表 collections . synchronizedmap(地图) ConcurrentHashMap

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

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


当前回答

Hashtable的“可伸缩性问题”在Collections.synchronizedMap(Map)中以完全相同的方式呈现——它们使用非常简单的同步,这意味着同一时间只有一个线程可以访问映射。

当您有简单的插入和查找时,这不是什么大问题(除非您做得非常密集),但是当您需要遍历整个Map时,这就变成了一个大问题,对于一个大型Map来说,这可能会花费很长时间——当一个线程这样做时,所有其他线程都必须等待,如果它们想要插入或查找任何东西。

ConcurrentHashMap使用非常复杂的技术来减少对同步的需求,并允许多线程在不同步的情况下进行并行读访问,更重要的是,它提供了一个不需要同步的迭代器,甚至允许在交互期间修改Map(尽管它不保证在迭代期间插入的元素是否会返回)。

其他回答

以下是一些例子:

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

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

哈希表和ConcurrentHashMap不允许空键或空值。 synchronizedmap (Map)同步所有操作(get、put、size等)。 ConcurrentHashMap支持检索的完全并发性,以及可调的更新预期并发性。

像往常一样,这涉及到并发性、开销和速度的权衡。您确实需要考虑应用程序的详细并发需求来做出决定,然后测试您的代码,看看它是否足够好。

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

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

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

同步地图:

Synchronized Map与Hashtable也没有太大区别,在并发Java程序中提供了类似的性能。哈希表和SynchronizedMap之间的唯一区别是SynchronizedMap不是遗留的,您可以使用Collections.synchronizedMap()方法包装任何Map来创建它的同步版本。

ConcurrentHashMap:

ConcurrentHashMap类提供了标准HashMap的并发版本。这是对Collections类中提供的synchronizedMap功能的改进。

与哈希表和同步映射不同,它从不锁定整个映射,而是将映射划分为段,并在这些段上锁定。如果读取线程的数量大于写入线程的数量,它的性能会更好。

默认情况下,ConcurrentHashMap被划分为16个区域,并应用了锁。这个默认值可以在初始化ConcurrentHashMap实例时设置。当在特定的段中设置数据时,将获得该段的锁。这意味着如果两个更新分别影响不同的存储桶,那么它们仍然可以同时安全执行,从而最大限度地减少锁争用,从而最大化性能。

ConcurrentHashMap不会抛出ConcurrentModificationException异常

如果一个线程试图修改它,而另一个线程正在遍历它,ConcurrentHashMap不会抛出ConcurrentModificationException

synchronizedmap和ConcurrentHashMap的区别

collections . synchronnizedmap (HashMap)将返回一个几乎相当于Hashtable的集合,其中Map上的每个修改操作都锁定在Map对象上,而对于ConcurrentHashMap,线程安全是通过根据并发级别将整个Map划分为不同的分区,只锁定特定的部分而不是锁定整个Map来实现的。

ConcurrentHashMap不允许空键或空值,而synchronized HashMap允许一个空键。

类似的链接

Link1

Link2

性能比较