jdk1.7中ConCurrentHashMap的size方法如何保证正确

我看论坛上都说是计算两次modCount,如何两次相同就认为没有改变。如果两次不同就加锁再计算一遍。

我的问题是为什么前两次一样就能认为没有改变?
例如,在计算第二次的时候,计算玩一个segment的modCount之后,这个segment有新增了一个。那计算的结果不就是错的吗?

阅读 3.3k
2 个回答

涉及到 modCount 改变的地方只有 put / remove 这些方法里,这些方法里全都有锁,并且需要注意的是,是 先执行的 modCount++、再执行的相应的增加或移除元素的操作

也就是你说的“这个 segment 又新增了一个”的时候,modCount 已经变化了,不会存在你说的问题。

如果 modCount 结果已经计算出了、“这个 segment 又新增了一个”,说明从执行顺序上,size 方法也是先执行的,它计算的是当时的容器大小。难道你想让 size 能预知下一刻的大小?

更何况高并发情况下要想取得精确值,你本身就应该加锁操作。

jdk7和jdk8实现方法不一样。

jdk8 是通过对 baseCount 和 counterCell 进行 CAS 计算,最终通过 baseCount 和 遍历 CounterCell 数组得出size,后者内部有volatile变量保证可见性。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题