ConcurrentHashMap之size()方法

白玉 IT哈哈

 /**     * 计算map中的key-value对总数     * 步骤:     * 1)遍历所有段,计算总的count值sum,计算总的modCount值     * 2)如果有数据的话(modCount!=0),再遍历所有段一遍,计算总的count值check,在这期间只要有一个段的modCount发生了变化,就再重复如上动作两次     * 3)若三次后,还未成功,遍历所有Segment,分别加锁(即建立全局锁),然后计算,最后释放所有锁     */    public int size() {        final Segment<K, V>[] segments = this.segments;        long sum = 0;//总量        long check = 0;//标志位        int[] mc = new int[segments.length];//存放每个段的modCount        for (int k = 0; k < RETRIES_BEFORE_LOCK; ++k) {            check = 0;            sum = 0;//总的count值            int mcsum = 0;//总的modCount值            for (int i = 0; i < segments.length; ++i) {//遍历所有段                sum += segments[i].count;//计算总的count值                mcsum += mc[i] = segments[i].modCount;//计算总的modCount值            }            if (mcsum != 0) {//有数据的话,再检查一遍                for (int i = 0; i < segments.length; ++i) {                    check += segments[i].count;//计算总的count                    if (mc[i] != segments[i].modCount) {//只要有一个段发生了变化(在遍历期间发生了增删变化)                        check = -1;                         break;//跳出所有循环                    }                }            }            if (check == sum)//成功                break;        }        if (check != sum) { //以上三次都为成功的话            sum = 0;            //每一个段全部加锁(相当于加了一个全局锁)            for (int i = 0; i < segments.length; ++i)                segments[i].lock();            //进行统计            for (int i = 0; i < segments.length; ++i)                sum += segments[i].count;            //全部解锁            for (int i = 0; i < segments.length; ++i)                segments[i].unlock();        }        if (sum > Integer.MAX_VALUE)            return Integer.MAX_VALUE;        else            return (int) sum;    }

在不加锁的情况下遍历所有Segment,读取每个Segment的count和modCount,并进行统计;
完毕后,再遍历一遍所有Segment,比较modCount,是否发生了变化,若发生了变化,则再重复如上动作两次;
若三次后,还未成功,遍历所有Segment,分别加锁(即建立全局锁),然后计算,最后释放所有锁。
注:以如上的方式,大部分情况下,不需要加锁就可以获取size()

更多相关文章

  1. jQuery遍历祖先元素:parentsUntil
  2. jQuery在点击按钮上迭代/循环遍历数据表
  3. jQuery遍历----------(遍历、祖先、后代、同胞、过滤)
  4. jQuery遍历Table tr td td中包含标签
  5. 是否有更快的方法来遍历HTMLDocument中的每一个元素呢?
  6. php逐个汉字遍历字符串
  7. Javascript学习:案例7--对象属性和方法的遍历、删除、添加.html
  8. 利用javascript实现遍历xml文件的代码实例
  9. js中ajax获取json数据遍历提示undefined

随机推荐

  1. Android 问题汇总
  2. 自动换行
  3. Android 代码改变图片颜色android:tint="
  4. Android中让View匀速旋转
  5. Android 底部导航栏中间凸起、越界显示
  6. Android 默认水波纹的使用和去除
  7. android开发之android:padding和android:
  8. EditText 文字验证
  9. Windows下git下载android source
  10. Android 获取手机卡相关信息