【问题标题】:A clarification about ConcurrentHashMap javadoc关于 ConcurrentHashMap javadoc 的说明
【发布时间】:2013-07-13 09:02:32
【问题描述】:

下面这句话的最后一点我不太清楚:

检索操作(包括get)一般不会阻塞,所以可能 与更新操作重叠(包括放置和删除)。检索 反映最近完成的更新操作的结果 坚持他们的发病。 对于 putAll 和 明确的,并发检索可能只反映插入或删除 一些条目。

为什么只针对某些条目?

【问题讨论】:

    标签: java map concurrency


    【解决方案1】:

    可能只看到“一些”更改,因为另一个线程可能会在期间访问地图 putAll()clear(),这两个都需要许多步骤才能完成,而只有 部分完成。

    【讨论】:

      【解决方案2】:

      第一部分和最后一部分必须一起阅读才能有意义。分解它,我们得到:

      • 检索操作(包括 get)一般不会阻塞,因此它们可能与更新操作重叠
      • 检索反映了最近完成的更新操作在开始时保持的结果

      现在,考虑putAll 的情况(这是 ConcurrentHashMap.java 源代码):

      for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
          put(e.getKey(), e.getValue());
      

      请注意,它会将每个条目循环添加到地图中。如果您使用 100 个条目调用 putAll,并且在 50% 的过程中,另一个线程尝试从映射中 get 一个值,那么当时只有 50 个提供给 putAll 的条目可用。

      特别是:文档并未通知您 特定 条目将不可用,只是在您调用 get 之前整个聚合操作可能不完整另一个线程,因为它们彼此不同步。

      【讨论】:

        【解决方案3】:

        putAllclear 不是原子操作。因此,如果一个线程调用putAll 来放置几个条目,而另一个线程并行检索值,它可能会看到putAll 操作的中间状态。在 putAll 方法完成之前,地图不会阻塞。 (清除也是如此 - 清除操作并行运行时,可以检索值)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-06-23
          • 2019-08-29
          • 2019-05-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多