我看论坛上都说是计算两次modCount,如何两次相同就认为没有改变。如果两次不同就加锁再计算一遍。
我的问题是为什么前两次一样就能认为没有改变?
例如,在计算第二次的时候,计算玩一个segment的modCount之后,这个segment有新增了一个。那计算的结果不就是错的吗?
我看论坛上都说是计算两次modCount,如何两次相同就认为没有改变。如果两次不同就加锁再计算一遍。
我的问题是为什么前两次一样就能认为没有改变?
例如,在计算第二次的时候,计算玩一个segment的modCount之后,这个segment有新增了一个。那计算的结果不就是错的吗?
jdk7和jdk8实现方法不一样。
jdk8 是通过对 baseCount 和 counterCell 进行 CAS 计算,最终通过 baseCount 和 遍历 CounterCell 数组得出size,后者内部有volatile变量保证可见性。
10 回答11.2k 阅读
15 回答8.4k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
8 回答6.3k 阅读
2 回答2.7k 阅读✓ 已解决
3 回答5.1k 阅读✓ 已解决
涉及到
modCount
改变的地方只有put
/remove
这些方法里,这些方法里全都有锁,并且需要注意的是,是 先执行的 modCount++、再执行的相应的增加或移除元素的操作。也就是你说的“这个 segment 又新增了一个”的时候,
modCount
已经变化了,不会存在你说的问题。如果
modCount
结果已经计算出了、“这个 segment 又新增了一个”,说明从执行顺序上,size
方法也是先执行的,它计算的是当时的容器大小。难道你想让size
能预知下一刻的大小?更何况高并发情况下要想取得精确值,你本身就应该加锁操作。