如果有 ConcurrentHashMap,为啥需要 synchronizedMap()? [复制]

Posted

技术标签:

【中文标题】如果有 ConcurrentHashMap,为啥需要 synchronizedMap()? [复制]【英文标题】:Why need synchronizedMap() if there is ConcurrentHashMap? [duplicate]如果有 ConcurrentHashMap,为什么需要 synchronizedMap()? [复制] 【发布时间】:2017-08-24 02:45:33 【问题描述】:

我阅读了一篇关于线程安全映射的文章并提出了一个问题。 Collections.synchronizedMap() 代理底层映射,在每个方法上添加 synchronized 块。另一方面,ConcurrentHashMap 不会在读/写操作上锁定整个地图。这意味着多线程系统中的所有操作都更快。

那么现在使用synchronizedMap() 有什么好处呢?我只看到了:

    它从 java 1.2 开始可用(与 java 1.5 相比 ConcurrentHashMap) 可以存储可以为空的值(如果底层地图可以做到的话)

还有其他情况synchronizedMap()更好吗?

【问题讨论】:

如果要同步的地图不是HashMap CHM 允许更高的并行化和可扩展性,但增加的复杂性会消耗额外的内存和性能,因此在低争用环境中可能不值得。此外,synchronizedMap() 可以包装各种地图类型,例如 EnumMapLinkedHashMap 【参考方案1】:

Collections.synchronizedMap(map)ConcurrentHashMap 各有利弊。

synchronizedMap 在您需要数据一致性时很有用。每个访问线程都会有一个地图的更新视图,这是通过阻塞地图来实现的,这反过来又会降低其性能。

ConcurrentHashMap 在您需要频繁修改map 时很有用。由于它适用于map 的分段/分区,因此多个线程同时在其上工作。但是有可能访问线程可能没有地图的更新视图。另一个优点是它是fail-safeConcurrentHashMap 不允许空键或空值。

使用ConcurrentHashMap如果高度关注性能然后数据一致性。

【讨论】:

这不太对。 ConcurrentHashMap 对表格进行分段。默认为 16,但您可以传递更高的值。这意味着您有 1/16 的机会正在访问的条目将被另一个进程锁定。因此,您将始终拥有最新的地图图片,但性能损失的可能性较小,而使用 synchronizedMap 时,整个事情都会被锁定。 @robert,您所说的ConcurrentHashMap 分段是正确的,我并不是说ConcurrentHashMap 在访问地图时不会提供更新的地图视图。但是有可能ConcurrentHashMap在高并发环境下不会返回更新的地图视图。 我想这取决于你如何定义“更新” - 读取不会反映任何待处理的写入......但它是尚未进行的写入,而不是返回的读取过时的价值。我认为您的答案只需要澄清一下即可。【参考方案2】:

我可以借助互斥量与信号量的类比来翻译它。

就像任何 Mutex 一样,synchronizedMap 一次只允许一个线程访问支持映射。这确保没有其他线程能够从映射中读取/写入条目。

对于 ConcurrentHashMap,就像信号量一样,我们决定一个并发级别,即一次有多少线程可以实际进入并查看 Map 中的条目。

关于何时使用 Mutex 以及何时使用 Semaphore 的研究可以帮助您进一步消除疑虑。

【讨论】:

【参考方案3】:

来自 ConcurrentHashMap 文档:

"...不支持以某种方式锁定整个表 阻止所有访问"

在遍历 ConcurrentHashMap 元素时,您可能会看到其他线程同时完成更新。如果您想阻止此类更新,您可以使用 Collections.synchronizedMap() 并将迭代逻辑放在 synchronized(map) 块中。

【讨论】:

【参考方案4】:

不是真的。我能想到的唯一另一种情况是轻松地使自定义地图实现线程安全。

【讨论】:

以上是关于如果有 ConcurrentHashMap,为啥需要 synchronizedMap()? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 7 ConcurrentHashMap 中,为啥在写的时候需要段锁?为啥我们不能再次使用 Unsafe 来保持非阻塞?

70%的Java程序员不知道为啥 ConcurrentHashMap 读操作不需要加锁?

java8 中concurrenthashmap数据结构和HashMap一样,且线程安全 为啥还要HashMap

Java8 中 ConcurrentHashMap工作原理的要点分析

如果我的用户与我的 AspNetCore webapp 上的所需角色相关联,为啥我会被禁止?

HashMap,,ConcurrentHashMap------------------浅谈!!