我对以下引用的最后一点不太清楚:
检索操作(包括get)一般不会阻塞,因此可能与更新操作重叠(包括put和remove) . 检索反映了最近完成的更新操作的结果 . 对于诸如putAll和clear之类的聚合操作,并发检索可能反映仅插入或删除某些条目 .
为什么只有一些条目?
必须一起阅读第一部分和最后部分才有意义 . 打破它,我们得到:
检索操作(包括get)通常不会阻塞,因此它们可能与更新操作重叠
检索反映了最近完成的更新操作的结果
现在,考虑一下 putAll (这是ConcurrentHashMap.java源)的情况:
putAll
for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) put(e.getKey(), e.getValue());
请注意,它会在循环中将每个条目添加到 Map 中 . 如果您使用100个条目调用 putAll ,并且50%通过,则另一个线程尝试从 Map 中获取 get 值,此时只有50个给 putAll 的条目可用 .
get
具体来说:文档没有通知您特定条目将不可用,只是在您在另一个线程中调用 get 之前可能没有完成整个聚合操作,因为它们彼此不同步 .
只有"some"的更改可能会被看到,因为另一个线程可能会在 putAll() 或 clear() 期间访问 Map ,这两个步骤都需要很多步骤才能完成,只需完成一部分 .
putAll()
clear()
putAll 和 clear 不是原子操作 . 因此,如果一个线程调用 putAll 来放置几个条目而另一个线程并行检索值,则可能会看到 putAll 操作的中间状态 . 在 putAll 方法完成之前, Map 不会阻止 . (清除相同 - 在清除操作并行运行时可以检索值) .
clear
3 回答
必须一起阅读第一部分和最后部分才有意义 . 打破它,我们得到:
检索操作(包括get)通常不会阻塞,因此它们可能与更新操作重叠
检索反映了最近完成的更新操作的结果
现在,考虑一下
putAll
(这是ConcurrentHashMap.java源)的情况:请注意,它会在循环中将每个条目添加到 Map 中 . 如果您使用100个条目调用
putAll
,并且50%通过,则另一个线程尝试从 Map 中获取get
值,此时只有50个给putAll
的条目可用 .具体来说:文档没有通知您特定条目将不可用,只是在您在另一个线程中调用
get
之前可能没有完成整个聚合操作,因为它们彼此不同步 .只有"some"的更改可能会被看到,因为另一个线程可能会在
putAll()
或clear()
期间访问 Map ,这两个步骤都需要很多步骤才能完成,只需完成一部分 .putAll
和clear
不是原子操作 . 因此,如果一个线程调用putAll
来放置几个条目而另一个线程并行检索值,则可能会看到putAll
操作的中间状态 . 在putAll
方法完成之前, Map 不会阻止 . (清除相同 - 在清除操作并行运行时可以检索值) .