03键值对的数量是如何保存到 baseCount 和 counterCells 中的呢?
addCount(),它会先对CHM中所有键值对计数,然后考虑是否扩容。现在我们来看看它是如何计数的。privatefinalvoidaddCount(longx,intcheck){CounterCell[]as;longb,s;//第一层ifif((as=counterCells)!=null||!U.compareAndSwapLong(this,BASECOUNT,b=baseCount,s=b+x)){CounterCella;longv;intm;booleanuncontended=true;//第二层ifif(as==null||(m=as.length-1)<0||(a=as[ThreadLocalRandom.getProbe()&m])==null||!(uncontended=U.compareAndSwapLong(a,CELLVALUE,v=a.value,v+x))){fullAddCount(x,uncontended);return;}if(check<=1)return;s=sumCount();}if(check>=0){...}}addCount()中有两层if,其中蕴含了非常巧妙的设计,第一层:counterCells不为空:跳转第二层if;counterCells为空:不着急创建counterCells,先用原子操作增加baseCount:成功:结束计数;失败:跳转第二层if。第二层if就是用来创建counterCells以及使用它来计数的:counterCells为空或counterCells[probe]为空:调用fullAddCount(x,true);counterCells[probe]已经创建:原子操作增加其value值:成功:结束计数;失败:调用fullAddCount(x,false)。
来自:容器和Map-CocurrentHashMap 1.7和1.8