<= 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)
推荐阅读
-
-
-
-
-
开发一站式购物平台(app),支持淘宝、京东、当当、卓越,技术上可行吗大致该咋做
-
#孩子#疫情期间,如何帮助孩子养成健康的生活作息?
-
-
-
饺子|夏天此菜要多吃,钙是鸡肉的7倍,只要1元一斤,用来包饺子超级香
-
鞭牛士|薇娅与其丈夫间接持股40%,杭州爱娅生物科技有限公司注销
-
烹饪|15块钱一斤的石斑鱼,教你清蒸石斑鱼的做法,肉质鲜嫩,营养丰富
-
凯迪拉克·上海音乐厅年末发布“初心向前——2021音乐季1月-7月音乐会”精心策划演出,献礼建党百年
-
玩懂手机华为Mate X2折叠屏新机3C认证曝光:支持66W快充
-
丝瓜|这碗汤我家一周要喝10次,鲜美又滋补,秋天常喝让皮肤嫩得出水
-
炸杏鲍菇怎么做不软还酥脆 炸杏鲍菇如何做不软还酥脆
-
「食材」大胃王挑战80个“炸鸡腿”,转换镜头一看穿帮,直接掉粉70万!
-
-
练瑜伽美图|圈粉百万,又燃又励志!肥宅减重20斤成健身博主
-
「爱笑的傻猫」幽默笑话:让你知道什么叫做好马不吃回头草
-