ConcurrentHashmap的CounterCells

CounterCells解释

ConcurrentHashMap是采用CounterCell数组来记录元素个数的,像一般的集合记录集合大小,直接定义一个size的成员变量即可,当出现改变的时候只要更新这个变量就行。为什么ConcurrentHashMap要用这种形式来处理呢? 问题还是处在并发上,ConcurrentHashMap是并发集合,如果用一个成员变量来统计元素个数的话,为了保证并发情况下共享变量的的安全,势必会需要通过加锁或者自旋来实现,如果竞争比较激烈的情况下,size的设置上会出现比较大的冲突反而影响了性能,所以在ConcurrentHashMap采用了分片的方法来记录大小,具体什么意思,我们来分析下

public class ConcurrentHashMap extends Abstract{

...


private transient volatile int cellsBusy;// 标识当前cell数组是否在初始化或扩容中的CAS标志位

/**

* Table of counter cells. When non-null, size is a power of 2.

*/

private transient volatile CounterCell[] counterCells;// counterCells数组,总数值的分值分别存在每个cell中

 

@sun.misc.Contended static final class CounterCell {

volatile long value;

CounterCell(long x) { value = x; }

}

//看到这段代码就能够明白了,CounterCell数组的每个元素,都存储一个元素个数,而实际我们调用size方法就是通过这个循环累加来得到的

//又是一个设计精华,大家可以借鉴; 有了这个前提,再会过去看addCount这个方法,就容易理解一些了
final long sumCount() {
        CounterCell[] as = counterCells; CounterCell a;
        long sum = baseCount;
        if (as != null) {
            for (int i = 0; i < as.length; ++i) {
                if ((a = as[i]) != null)
                    sum += a.value;
            }
        }
        return sum;
    }

 

你可能感兴趣的:(java基础)