3

提供ConcurrentHashMap线程安全但文档状态:

“然而,即使所有操作都是线程安全的,检索操作并不需要锁定”

因此,据我所知,获取或设置键和值是线程安全的,但修改任何给定键的实际值不是(我实际上指的是该对象的值或状态)。

我只是对它是如何工作的感到困惑,目前我认为事情是这样的。

ConcurrentHashMap就设置/获取它们而言,密钥的唯一保证是线程安全的。但是您放在地图中的对象必须自己保护并发。

它是否正确?

4

3 回答 3

3

但是您放在地图中的对象必须自己保护并发。

你的理解是正确的。

文档中:

但是,即使所有操作都是线程安全的,检索操作也不需要锁定,并且不支持以阻止所有访问的方式锁定整个表。

上面还说的是,在读取时没有内置的哈希映射自动锁定机制。特别是,这意味着get()操作可以与其他线程执行的并发修改重叠。

该文档继续解释并发语义:

检索操作(包括get)一般不会阻塞,因此可能与更新操作(包括putand remove)重叠。检索反映了最近完成的更新操作在其开始时保持的结果。putAll对于和等聚合操作clear,并发检索可能仅反映插入或删除某些条目。同样,在迭代器/枚举创建时或之后的某个时间点,返回反映哈希表状态的元素IteratorsEnumerations

于 2012-05-28T19:45:25.783 回答
2

您所说的默认情况下是正确的 - 地图无法强制其键或其值的线程安全,因为这些是来自外部的对象。但是,您所读到的有关对象检索的内容与该事实无关。检索值时映射不会阻塞,因此可能同时发生另一个更新(这些操作可能重叠)。

于 2012-05-28T19:47:18.667 回答
1

The basic idea of the ConcurrentHashMap is that only modifications use a lock, while retrieval-only operations don't. This is possible because the entire data structure and the operations on it are defined in a way that allows get() to only ever see a "consistent enough" state of the map to do its work. If there's currently an insert operation in progress, then get() either sees the result or it doesn't, but it won't ever see a partial result or even temporarily invalid data.

于 2012-05-28T20:00:58.277 回答