java - ConcurrentHashMap 包含值,但 size() 方法返回 0

标签 java multithreading collections concurrency

遇到 ConcurrentHashMap 的奇怪行为:首先,多个线程使用 putIfAbsent()remove( )。一段时间后(几十秒甚至一分钟)另一个线程使用两种方法检查 map 是否为空:

  1. 调用 myMap.isEmpty() 方法
  2. 尝试查看迭代器中是否有任何条目:myMap.entrySet().iterator().hasNext()

令人惊讶的是,这两种方法给出了不同的结果。 isEmpty() 返回 true 并且 iterator.hasNext() 紧随其后返回 true。调用之间没有任何暂停,此时没有在 map 上执行写入操作。

请注意,根据日志,没有 isEmpty() 返回 falseiterator.hasNext() 返回 false 同时。所以总是 isEmpty() 方法没有“看到” map 中的任何条目。

想知道这是否是 ConcurrentHashMap 的预期行为。

文档指出:

Bear in mind that the results of aggregate status methods including size, isEmpty, and containsValue are typically useful only when a map is not undergoing concurrent updates in other threads. Otherwise the results of these methods reflect transient states that may be adequate for monitoring or estimation purposes, but not for program control.

这给出了这样的想法,即当没有正在进行的写操作时,size()isEmpty() 等方法应该返回与映射的实际内容一致的值.

最佳答案

ConcurrentHashMap.getEntrySet() 的 javadoc 告诉您从集合中获得的迭代器弱一致性

java.util.concurrent 包的 Javadoc 解释了“弱一致性”的含义:

... their Iterators and Spliterators provide weakly consistent rather than fast-fail traversal:

  • they may proceed concurrently with other operations
  • they will never throw ConcurrentModificationException
  • they are guaranteed to traverse elements as they existed upon construction exactly once, and may (but are not guaranteed to) reflect any modifications subsequent to construction.

最后一个项目符号很重要。它告诉您迭代器是创建迭代器时映射中的内容的 View 。如果您随后更改 map 的内容,迭代器的内容不会更改。

关于java - ConcurrentHashMap 包含值,但 size() 方法返回 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36128804/

相关文章:

java - Tomcat 服务器未启动。在 eclipse 中

java - GridBagLayout,如何在放置组件时阻止屏幕拉伸(stretch)?

java - volatile 和同步化解决竞争条件: Singleton Member Field

multithreading - 通过 block 完成在后台查找对象

java - 同步块(synchronized block)抛出 DuplicateKeyException

java - Windows 10 更新后 Android Studio 上的 Gradle 同步失败

java - 将 JLabel 与 JCheckBox 的文本对齐

c# - 为什么 C# 不为集合实现 GetHashCode?

java - 自定义列表上的二进制搜索 - android

java - 是否有更好的方法来分区列表和批量处理以更改源列表