ConcurrentHashMap中如何同时对同一个segment进行两个读操作?

问题描述

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

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

解决方法

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

这是不对的。根据{{​​3}},“检索操作需要锁定”[强调原文]。这意味着任意多个线程可以一次读取地图。 (注意:上面的链接是最新版本 Java 的文档,但所有版本都是如此。上面引用的语句从 the ConcurrentHashMap documentation 开始就存在了,这是 ConcurrentHashMap 被引入的初始版本。 )

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

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

Hashtable.get 锁定整个映射,因此并发读取是相同元素还是不同元素无关紧要;无论哪种方式,一个锁定另一个。

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