【问题标题】:Is read operation in ConcurrentHashMap reliable regarding the return value?ConcurrentHashMap 中的读取操作对于返回值是否可靠?
【发布时间】:2015-08-27 14:50:40
【问题描述】:

我在ConcurrentHashmap 中阅读的书中阅读并不能保证最近更新的状态,它有时可以给出更接近的值。这是正确的吗?

我已经阅读了它的 javadocs 和许多博客,它们似乎另有说法(即它是准确的)。

哪一个是真的?

【问题讨论】:

标签: java multithreading concurrenthashmap


【解决方案1】:

直观地说,ConcurrentHashMap 应该表现得像一组 volatile 变量;映射键是变量地址。 get(key)put(key, value) 的行为应该类似于 volatile 读写。

这在文档中没有明确说明。但是,我坚信确实如此。否则会有很多意想不到的、令人惊讶的行为破坏应用程序逻辑。 我认为 Doug Lea 不会对我们这样做。可以肯定的是,有人请在concurrency-interest 邮件列表中询问他。

假设它确实遵循 volatile 语义,我们可以基于 Java 内存模型进行推理 -

所有易失性读取和写入形成一个单一的总订单。这可以被认为是一条伪时间线,其中读取/写入是其上的点。

易失性读取看到前一个易失性写入,并且只看到那个写入。这里的“先行”是根据伪时间线。

伪时间线可以不同于“真实”时间线。但是,理论上,volatile write 不能在伪时间线上无限推迟。而且,在实践中,两条时间线非常接近。

因此,我们可以非常确定,易失性写入应该“非常快”地对读取可见。

【讨论】:

  • ...volatile 变量...实际上,它ConcurrentHashMap API 合同中声明的,但不是在那些话中。 Javadoc 说,“...对给定键的更新操作与该键的任何(非空)检索具有 happens-before 关系。”这与 JLS 中描述 volatile 的方式基本相同:对 volatile 字段的更新建立 happens-before 以及随后对同一字段的读取。
  • @jameslarge - 是的,但这只是 volatile 语义的一部分。我们还需要synchronization-ordersynchronization-order consistency
  • 也许更好的问题是,ConcurrentHashMap 操作是否*顺序一致”。我想它一定是;或者至少,人们认为这是理所当然的。
【解决方案2】:

这就是并发的本质。如果当前挂起的写操作未安全完成,任何并发集合都可能在字段中为您提供旧值。在所有情况下,这都是您所期望的。如果您从多个线程访问它们,为并发创建的集合不会给您损坏的值或中断,但如果未完成写入,它们可能会给您旧值。

【讨论】:

  • 如果该值没有被覆盖,那么它不是旧值,它是当前值......当然它不会给你未来的值,这很正常
  • 是的。但是在并发的情况下,可以在写入时读取值。如果发生这种情况,“正常”集合会做一些未定义的事情。并发集合为您提供旧值或阻塞,直到写入完成。
  • 您不能为此查看Collections.SynchronizedCollection。这是一个围绕普通集合的简单低性能阻塞包装器。看看 ConcurrentHashMap 的实现。
  • 嗯好的,那么我认为您的回答应该清楚表明这只是由于ConcurrentHashMap 的实现而不是所有并发集合的性质
【解决方案3】:

来自ConcurrentHashMap javadoc

检索操作(包括 get)一般不会阻塞,因此可能与更新操作(包括 put 和 remove)重叠。检索反映了最近完成的更新操作在其开始时保持的结果。对于 putAll 和 clear 等聚合操作,并发检索可能仅反映插入或删除某些条目。类似地,迭代器和枚举返回反映哈希表在创建迭代器/枚举时或之后的某个时间点的状态的元素。它们不会抛出 ConcurrentModificationException。但是,迭代器被设计为一次只能由一个线程使用。

需要强调的一点是Iterator 不会反映在创建Iterator 之后所做的更改。因此,如果您需要迭代映射的值,而其他线程正在添加到映射,并且您关心映射的最新状态,那么使用 ConcurrentHashMap 可能不是您需要的映射实现.

【讨论】:

  • 感谢清理。看起来好多了!
  • Collections.synchronizedMap 似乎同步了 all 访问。为什么选择ConcurrentHashMap 的设计?
猜你喜欢
  • 2019-08-13
  • 2016-01-11
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 2021-07-27
  • 1970-01-01
  • 2013-06-11
相关资源
最近更新 更多