gpt4 book ai didi

java - 关于并发 HashMap 的事实

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:52:51 25 4
gpt4 key购买 nike

我从不同的来源阅读了一些关于 ConcurrentHashmap 的陈述,并想验证它们是否确实如此。

  1. ConcurrentHashmap 的迭代器创建后,只有线程的删除和更新操作才能保证得到反射(reflect)。编辑/删除后迭代器是否刷新其快照?为什么迭代器对待更新/删除的方式与 ADD 完全不同。

  2. ConcurrentHashmap 将其数据分成多个段以减少写入器锁争用。 concurrencyLevel 参数直接指定类内部创建的分片数。如果我们简单地使用无参数构造函数,并接受默认配置, map 将在您添加第一个值之前实例化 16 个分片所需的对象……这里的分片是什么意思?它是 map 中的一桶数据 - 还是整个 map 的副本。我理解这个类似于数据库中的一个页面,可以独立锁定fur update。为什么 concurrencyLevel 会影响内存?

最佳答案

Does the iterator refresh its snapshot after an edit/remove?Why would the iterator treat an update/remove any differently than an ADD.

CHM 的迭代器在 API 中这样解释

Similarly, Iterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration.

意味着返回的 Iterator 可能反射(reflect)也可能不反射(reflect)迭代时 Map 中发生的更改。想象一下,如果您创建迭代器并遍历整个段并转到下一个段。转到下一段后,您完成遍历的第一段已完成添加或删除。好吧,你不会看到那个,没关系,它没有违反 API。

关于你的第二个问题。添加是隐含的,添加和删除之间的可见性没有区别。

Why would the concurrencylevel impact memory then?

自 ConcurrentHashMap 发布以来,内存一直是一个问题。默认情况下,每个并发级别都会创建一个单独的 Segment。该段有一个 HashEntry 表,也是一个可重入锁(因此也是所有必需品)。

Java 8 发布 CHMv8这实际上解决了这个问题。

你可以阅读更多关于内存的信息here ,具体来说:

Whilst doing a memory profile, JVisualVM showed that the top culprit was the ConcurrentHashMap.Segment class. The default number of segments per ConcurrentHashMap is 16. The HashEntry tables within the segments would probably be tiny, but each Segment is a ReentrantLock. Each ReentrantLock contains a Sync, in this case a NonFairSync, which is a subclass of Sync and then AbstractQueuedSynchronizer. Each of these contains a queue of nodes that maintain state of what is happening with your threads. It is used when fairness is determined. This queue and the nodes use a lot of memory.

关于java - 关于并发 HashMap 的事实,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15885625/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com