ConcurrentHashMap
提供线程安全但文档状态:
“但是,即使所有操作都是线程安全的,检索操作也不需要锁定”
因此我明白获取或设置键和值是线程安全的,但是修改任何给定键的实际VALUE不是(通过值,我通常意味着该对象的值或状态)。
我只是对这是如何工作感到困惑,此刻我认为事情是这样的。
ConcurrentHashMap
只有gaurantees密钥在设置/获取它们方面是线程安全的。但是你放在地图中的对象本身必须要求并发。
这是对的吗?
答案 0 :(得分:2)
但是你放在地图中的对象本身必须要求并发。
您的理解是正确的。
但是,即使所有操作都是线程安全的,检索操作也不需要锁定,并且没有任何支持以阻止所有访问的方式锁定整个表。
上述内容也就是说,在读取过程中没有内置的自动锁定哈希映射的机制。特别是,这意味着get()
操作可能与其他线程执行的并发修改重叠。
该文档继续解释并发语义:
检索操作(包括
get
)通常不会阻止,因此可能与更新操作重叠(包括put
和remove
)。检索反映了最近完成的更新操作的结果。对于putAll
和clear
等聚合操作,并发检索可能反映仅插入或删除某些条目。类似地,Iterators
和Enumerations
返回反映在迭代器/枚举创建时或之后某个时刻哈希表状态的元素。
答案 1 :(得分:1)
默认情况下,您所说的是正确的 - 地图无法强制执行其键或其值的线程安全性,因为这些是来自外部的对象。然而,您阅读的关于对象检索的内容与该事实无关。检索值时地图不会阻塞,因此可能同时发生另一次更新(这些操作可能会重叠)。
答案 2 :(得分:0)
ConcurrentHashMap的基本思想是只有修改才使用锁,而仅检索操作则不然。这是可能的,因为整个数据结构及其上的操作是以允许get()
只能看到地图的“足够一致”状态来完成其工作的方式定义的。如果当前正在进行插入操作,那么get()
要么看到结果,要么看不到,但它不会看到部分结果,甚至看不到暂时无效的数据。