试图了解ConcurrentHashMap的范围

时间:2012-05-28 19:43:09

标签: java concurrency concurrenthashmap

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

  

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

因此我明白获取或设置键和值是线程安全的,但是修改任何给定键的实际VALUE不是(通过值,我通常意味着该对象的值或状态)。

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

ConcurrentHashMap只有gaurantees密钥在设置/获取它们方面是线程安全的。但是你放在地图中的对象本身必须要求并发。

这是对的吗?

3 个答案:

答案 0 :(得分:2)

  

但是你放在地图中的对象本身必须要求并发。

您的理解是正确的。

来自documentation

  

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

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

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

  

检索操作(包括get)通常不会阻止,因此可能与更新操作重叠(包括putremove)。检索反映了最近完成的更新操作的结果。对于putAllclear等聚合操作,并发检索可能反映仅插入或删除某些条目。类似地,IteratorsEnumerations返回反映在迭代器/枚举创建时或之后某个时刻哈希表状态的元素。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

ConcurrentHashMap的基本思想是只有修改才使用锁,而仅检索操作则不然。这是可能的,因为整个数据结构及其上的操作是以允许get()只能看到地图的“足够一致”状态来完成其工作的方式定义的。如果当前正在进行插入操作,那么get()要么看到结果,要么看不到,但它不会看到部分结果,甚至看不到暂时无效的数据。