<= sc || n >= MAXIMUM_CAPACITY)break;//扩容else if (tab == table) {int rs = resizeStamp(n);//sc<0表示 , 已经有其他线程正在扩容if (sc < 0) {Node[] nt;/**1 (sc >>> RESIZE_STAMP_SHIFT) != rs :扩容线程数 > MAX_RESIZERS-12 sc == rs + 1 和 sc == rs + MAX_RESIZERS :表示什么???3 (nt = nextTable) == null :表示nextTable正在初始化4 transferIndex <= 0 :表示所有hash桶均分配出去*///如果不需要帮其扩容 , 直接返回if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||transferIndex <= 0)break;//CAS设置sizeCtl=sizeCtl+1if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))//帮其扩容transfer(tab, nt);}//第一个执行扩容操作的线程 , 将sizeCtl设置为:(resizeStamp(n) << RESIZE_STAMP_SHIFT) + 2)else if (U.compareAndSwapInt(this, SIZECTL, sc,(rs << RESIZE_STAMP_SHIFT) + 2))transfer(tab, null);}}}此段代码参考网址:
transfer方法private final void transfer(Node[] tab, Node[] nextTab) {int n = tab.length, stride;//计算需要迁移多少个hash桶(MIN_TRANSFER_STRIDE该值作为下限 , 以避免扩容线程过多)if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE)stride = MIN_TRANSFER_STRIDE; // subdivide rangeif (nextTab == null) {// initiatingtry {//扩容一倍@SuppressWarnings("unchecked")Node[] nt = (Node[])new Node,?>[n << 1];nextTab = nt;} catch (Throwable ex) {// try to cope with OOMEsizeCtl = Integer.MAX_VALUE;return;}nextTable = nextTab;transferIndex = n;}int nextn = nextTab.length;ForwardingNode fwd = new ForwardingNode(nextTab);boolean advance = true;boolean finishing = false; // to ensure sweep before committing nextTab//1 逆序迁移已经获取到的hash桶集合 , 如果迁移完毕 , 则更新transferIndex , 获取下一批待迁移的hash桶//2 如果transferIndex=0 , 表示所以hash桶均被分配 , 将i置为-1 , 准备退出transfer方法for (int i = 0, bound = 0;;) {Node f; int fh;//更新待迁移的hash桶索引while (advance) {int nextIndex, nextBound;//更新迁移索引i 。if (--i >= bound || finishing)advance = false;else if ((nextIndex = transferIndex) <= 0) {//transferIndex<=0表示已经没有需要迁移的hash桶 , 将i置为-1 , 线程准备退出i = -1;advance = false;}//当迁移完bound这个桶后 , 尝试更新transferIndex ,, 获取下一批待迁移的hash桶else if (U.compareAndSwapInt(this, TRANSFERINDEX, nextIndex,nextBound = (nextIndex > stride ?nextIndex - stride : 0))) {bound = nextBound;i = nextIndex - 1;advance = false;}}//退出transferif (i < 0 || i >= n || i + n >= nextn) {int sc;if (finishing) {//最后一个迁移的线程 , recheck后 , 做收尾工作 , 然后退出nextTable = null;table = nextTab;sizeCtl = (n << 1) - (n >>> 1);return;}if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, sc - 1)) {/**第一个扩容的线程 , 执行transfer方法之前 , 会设置 sizeCtl = (resizeStamp(n) << RESIZE_STAMP_SHIFT) + 2)后续帮其扩容的线程 , 执行transfer方法之前 , 会设置 sizeCtl = sizeCtl+1每一个退出transfer的方法的线程 , 退出之前 , 会设置 sizeCtl = sizeCtl-1那么最后一个线程退出时:必然有sc == (resizeStamp(n) << RESIZE_STAMP_SHIFT) + 2) , 即 (sc - 2) == resizeStamp(n) << RESIZE_STAMP_SHIFT*///不相等 , 说明不到最后一个线程 , 直接退出transfer方法if ((sc - 2) != resizeStamp(n)
推荐阅读
-
国际足球|「足坛趣味问答100期答案」今晚公布51-100期榜单,前5名有奖品
-
-
孕妇|这些你喜欢的零食都不能吃了?不一定,看完就明白了!怀孕时
-
预告|《部落冲突》:你以为八周年就完了?不对,重磅活动还在后头
-
「出名」河南一个不出名的小镇,把钢卷尺卖到了全世界
-
以史为鉴|18岁击败彼得大帝,卡尔十二世统领的瑞典有多强?,15岁继承王位
-
-
徐汇滨江|上海徐汇滨江亲水平台遭船只撞击 肇事船只已被控制
-
找工作办了个假的证书,入职了公司,现在很后悔,离职还是坦白?
-
卡哇伊|财源滚滚来,接住!发发发!,7月中旬开门红!属虎人
-
苏宁易购发布2020半年报:线上销售规模大增20%
-
国际足球|巴萨捡到宝了!17岁小将打入队史第9000球,本赛季已进6球!
-
-
丈夫崩溃!浙江数学女老师突然被迫离开讲台!医生:有人37岁就成了这样……
-
「华为」HMS又一重拳出击?谷歌追悔莫及,华为海外生态第一战干得漂亮!
-
-
游戏产业|电视机的春天来了,Xbox确认将推出xCloud串流棒,把其变成高性能主机
-
-
|重磅官宣!福建不再与劳森签约 不当言论或让他彻底无缘CBA
-