<= 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)
推荐阅读
-
阿里巴巴|跟着马云20年,那个兢兢业业不肯辞职的前台小妹,现在怎么样了?
-
-
我曾是160斤胖女人,58次相亲失败,减重50斤后,被小8岁男友表白
-
-
「娱乐略知三四」这才是京城第一大富豪,他家的四合院紧挨着故宫,家具全是金丝楠木
-
「运动」没错!那些不动”的动作带来的泵感可以把你虐哭?
-
瓦妮莎@心酸!去世仅102天 38岁瓦妮莎像60岁 球迷:5次怀孕1次流产 太惨
-
紫陌红尘|芝芝怼魏亚云,《亲爱的自己》第42-43集预告:思雨怼王子茹
-
女生|“口臭”会越来越严重,再不改真没人要了女生常吃3种零食
-
军迷次元喵|结果让所有小国绝望,击沉一艘航母有多难?美军做了一次测试
-
-
杭州市民卡|免费!杭州这个地方为户外工作者提供凉茶!更多便民服务→
-
宝妈小厨8|女性长出“小胡子”,剃掉还是拔掉?学会三招,或能让你告别尴尬
-
坠楼身亡:四川一小区住户家中起火 男孩从起火房屋坠楼身亡
-
-
乐普医生|只因少了一个步骤,突发胸痛,阿司匹林帮倒忙
-
陈先生|“循环证明”没完没了,证明“我爸是我爸”为什么就这么难
-
明星八卦|“陈情令”演员撞衫,宣璐和杨幂穿同款,孟子义撞上娜扎,于斌这个意外了!
-
-
#小米科技#一加8Pro对比小米10Pro, 谁更适合作为你的旗舰手机?