今天爱分享给大家带来ConcurrentHashMap 的size()方法如何实现同步的【面试题详解】,希望能够帮助到大家。
1) JDK 8 推荐使用mappingCount 方法(另外的叫size方法),因为这个方法的返回值是 long 类型,不会因为 size 方法是 int 类型限制最大值
2)在没有并发的情况下,使用一个名为 baseCount 的volatile 变量就足够了,当并发的时候,CAS 修改 baseCount 失败后,就会使用 CounterCell 类了,会创建一个这个对象,通常对象的 volatile value 属性是 1。在计算 size 的时候,会将 baseCount 和 CounterCell 数组中的元素的 value 累加,得到总的大小,但这个数字仍旧可能是不准确的。
3) 还有一个需要注意的地方就是,这个 CounterCell 类使用了 @sun.misc.Contended 注解标识,这个注解是防止伪共享的。是 1.8 新增的。使用时,需要加上 -XX:-RestrictContended 参数。size()/mappingCount()–>sumCount(){使用了baseCount变量和CounterCell数组},在put的时候调用了 addCount()方法
JDK1.7 和 JDK1.8 对 size 的计算是不一样的。 1.7 中是先不加锁计算三次,如果三次结果不一样在加锁JDK1.8 size 是通过对 baseCount 和 counterCell 进行 CAS 计算,最终通过 baseCount 和 遍历 CounterCell 数组得出 size。