【发布时间】:2013-07-13 09:02:32
【问题描述】:
下面这句话的最后一点我不太清楚:
检索操作(包括get)一般不会阻塞,所以可能 与更新操作重叠(包括放置和删除)。检索 反映最近完成的更新操作的结果 坚持他们的发病。 对于 putAll 和 明确的,并发检索可能只反映插入或删除 一些条目。
为什么只针对某些条目?
【问题讨论】:
标签: java map concurrency
下面这句话的最后一点我不太清楚:
检索操作(包括get)一般不会阻塞,所以可能 与更新操作重叠(包括放置和删除)。检索 反映最近完成的更新操作的结果 坚持他们的发病。 对于 putAll 和 明确的,并发检索可能只反映插入或删除 一些条目。
为什么只针对某些条目?
【问题讨论】:
标签: java map concurrency
可能只看到“一些”更改,因为另一个线程可能会在期间访问地图 putAll() 或 clear(),这两个都需要许多步骤才能完成,而只有 部分完成。
【讨论】:
第一部分和最后一部分必须一起阅读才能有意义。分解它,我们得到:
现在,考虑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 之前整个聚合操作可能不完整另一个线程,因为它们彼此不同步。
【讨论】:
putAll 和 clear 不是原子操作。因此,如果一个线程调用putAll 来放置几个条目,而另一个线程并行检索值,它可能会看到putAll 操作的中间状态。在 putAll 方法完成之前,地图不会阻塞。 (清除也是如此 - 当清除操作并行运行时,可以检索值)。
【讨论】: