【问题标题】:How does two read operations on the same segment at the same time work in ConcurrentHashMap?ConcurrentHashMap中如何同时对同一段进行两次读取操作?
【发布时间】:2021-03-14 06:53:02
【问题描述】:

我试图了解读取操作在 HashTable、HashMap 和 ConcurrentHashMap 内部是如何工作的。 ConcurrentHashMap 在内部分为大小为 32 的段。因此一次最多可以读取 32 个线程。当我们在 ConcurrentHashMap 中同时对同一段进行两次读取操作时会发生什么。

另外,我想知道在HashTable、HashMap中对同一个元素进行多次读取是如何工作的?

【问题讨论】:

  • 过去,即在 Java 8 之前,ConcurrentHashMap 使用可配置数量的段,而不是“大小为 32 的段”。

标签: concurrency hashmap hashtable


【解决方案1】:

ConcurrentHashMap 在内部分为大小为 32 的段。因此一次最多可以读取 32 个线程。

这是不正确的。根据the ConcurrentHashMap documentation,“检索操作需要锁定”[强调原文]。这意味着任意多个线程可以一次读取映射。 (注意:上面的链接是最新版本的 Java 的文档,但所有版本都是如此。上面引用的声明自 the documentation for JDK 1.5 以来一直存在,这是引入 ConcurrentHashMap 的初始版本。)

即使对于 确实 涉及锁定的更新,此陈述也不正确:自 Java 7 以来,ConcurrentHashMap 还没有被划分为“段”;回到当它被分割成段的时候,对并发来说重要的是段的数量,而不是它们的大小;段数是用户可配置的;并且默认的段数是 16,而不是 32。

另外,我想知道在HashTable、HashMap中对同一个元素进行多次读取是如何工作的?

Hashtable.get 锁住了整个map,所以并发读取是同一个元素还是不同元素都没有关系;无论哪种方式,一个锁定另一个。

HashMap 不担心并发;多个线程可以愉快地同时读取地图,但是在读取或其他更新的同时进行更新是不安全的。

【讨论】:

    猜你喜欢
    • 2017-03-05
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    • 2017-05-07
    • 2017-07-31
    • 1970-01-01
    • 2016-03-09
    相关资源
    最近更新 更多