【问题标题】:Concurrent collection size calculation并发集合大小计算
【发布时间】:2015-07-31 19:04:00
【问题描述】:

ConcurrentLinkedQueueConcurrentLinkedDequeueConcurrentSkipListSet 等 Java 标准库中的大多数集合的文档都附带以下免责声明:

请注意,与大多数集合不同,size 方法不是 恒定时间操作。由于这些的异步性质 集合,确定当前元素个数需要遍历 的元素,因此可能会报告不准确的结果,如果这 集合在遍历过程中被修改。

这是什么意思?为什么他们不能保留一个计数器(例如,AtomicInteger)并在调用 size() 时返回值?

是不是因为计数器必须同步,因此造成了阻塞点?

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

【问题讨论】:

  • 原子计数器肯定不好。

标签: java multithreading collections concurrency


【解决方案1】:

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

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

【讨论】:

  • 当然size() 不能完全信任,我接受。但我遇到的问题是遍历集合中的每个元素以计算它们的非恒定成本。但我想我对阻塞点的看法是对的?
  • @GustavKarlsson Peter 的第一句话确实说明了原因。队列操作的同步和缓存失效将非常昂贵。是的,你是对的,那里肯定会有瓶颈。这是ReentrantReadWriteLock 的主要问题之一
猜你喜欢
  • 2014-02-24
  • 2017-06-27
  • 2021-02-11
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
  • 2013-03-27
  • 2022-01-19
  • 2018-09-26
相关资源
最近更新 更多