Java标准库中的大多数集合的文档,例如ConcurrentLinkedQueue,ConcurrentLinkedDequeue和ConcurrentSkipListSet,附带以下免责声明:
请注意,与大多数集合不同,size方法不是 恒定时间操作。由于这些的异步性质 设置,确定当前元素数量需要遍历 如果这样,可能会报告不准确的结果 在遍历期间修改了集合。
这是什么意思?为什么他们不能保留一个计数器(例如,AtomicInteger),只返回调用size()
的值?
是因为计数器必须同步,因此会产生一个阻塞点吗?
作为旁注,ConcurrentHashMap似乎没有这个问题。这是为什么?查看源代码,似乎它使用保存在数组中的多个计数器,这些计数器在调用size()
时求和。是为了规避阻塞点还是有其他原因?
答案 0 :(得分:5)
使用共享资源来维护size()既昂贵又无用。 size()
一旦返回就可能不正确,因为您无法锁定集合,因此它可以在您调用它和获取值之间进行更改。
ConcurentHashMap采用相同的方法。方法返回之前size()可能不正确。