并发集合大小计算

Concurrent collection size calculation

Java 标准库中大多数集合的文档,例如 ConcurrentLinkedQueue, ConcurrentLinkedDequeue and ConcurrentSkipListSet 都附带以下免责声明:

Beware that, unlike in most collections, the size method is not a constant-time operation. Because of the asynchronous nature of these sets, determining the current number of elements requires a traversal of the elements, and so may report inaccurate results if this collection is modified during traversal.

这是什么意思?为什么他们不能保留一个计数器(比如,一个 AtomicInteger)而只保留 return 调用 size() 的值?

是不是因为计数器必须同步,所以造成瓶颈?

附带说明一下,ConcurrentHashMap 似乎没有这个问题。这是为什么?查看源代码,它似乎使用了保存在数组中的多个计数器,这些计数器在调用 size() 时求和。是为了绕开瓶颈还是另有原因?

使用共享资源来维护 size() 既昂贵又无用。 size() 一旦 returns 就可能不正确,因为您无法锁定集合,因此它可能会在调用它和获取值之间发生变化。

ConcurentHashMap 有相同的方法。在方法返回之前,size() 可能不正确。