好累呀,喝口水,咕咕咕---
transfer这个方法也很长,同样,也有几个细节,细节好多(苦笑),一点点看,第一部分
if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE)stride = MIN_TRANSFER_STRIDE;这里是确定每个线程负责的扩容区间,很好理解,如果 CPU 核数大于 1,计算出一个值,等于 1,那么设置区间也没意义,全都是你的 。最后和最小区间判断一下大小
private static final int MIN_TRANSFER_STRIDE = 16;然后来到初始化操作
if (nextTab == null) {// initiatingtry {@SuppressWarnings("unchecked")Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1];nextTab = nt;} catch (Throwable ex) {// try to cope with OOMEsizeCtl = Integer.MAX_VALUE;return;}nextTable = nextTab;transferIndex = n;}不知道大家注意到没有,这里竟然没有加锁,难道是 Doug 老爷子忘记了?
显然不是,那这里难道不用加锁吗,如果有 2 个线程同时执行初始化操作,那么 nextTable 指向的对象地址就会发生变化,从而产生错误,一开始阿轩读到这里也是很疑惑的

文章插图
心想,这里又是什么骚操作呀?后来把前后源码翻了一下,终于,哦------
来一起看看怎么回事
通过搜索得知,transfer 总共有 5 个地方用到

文章插图
第二个方法 helpTransfer 是 putVal 里的,如果节点的 hash 值等于-1,那么协助扩容,很明显,这会已经初始化过了
第三个方法 tryPresize,主要作用也是进行扩容的,和 transfer 的区别是,这个方法是当链表转红黑树的时候发现集合的容量小于 64 就会走到这个方法进行扩容,里面逻辑和 addCount 几乎差不多,所以我们直接看 addCount
if (sc < 0) {if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||transferIndex <= 0)break;if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))transfer(tab, nt);}else if (U.compareAndSwapInt(this, SIZECTL, sc,(rs << RESIZE_STAMP_SHIFT) + 2))transfer(tab, null);大家回忆一下,之前说过只有第一个通过 CAS 成功的线程才会进入第二个 if,其他的线程进入第一个 if,大家注意看,里面有一个很不起眼的判断条件是(nt = nextTable) == null,也就是说,在其他线程走到这个判断的时候,如果第一个进入的线程此时还没有完成初始化,那么会直接 break,跳出循环,不参与扩容 。所以除了第一个进去 transfer 的线程外,其他线程进入 transfer 一定是已经完成初始化了,所以,在 transfer 方法里面初始化才不需要加锁

文章插图
接着往下看,设置了 2 个临时变量 i=0,bound=0,然后进行死循环
while (advance) {int nextIndex, nextBound;if (--i >= bound || finishing)advance = false;else if ((nextIndex = transferIndex) <= 0) {i = -1;advance = false;}else if (U.compareAndSwapInt(this, TRANSFERINDEX, nextIndex,nextBound = (nextIndex > stride ?nextIndex - stride : 0))) {bound = nextBound;i = nextIndex - 1;advance = false;}}进入内部的 while 循环,第一次进入循环的时候会走到第三个 if,确定线程负责的扩容区间,后面再进入循环的时候会走到第一个 if,当自己负责的扩容区间全部扩容完毕后,如果此时所有区间都已经分配完了,会进入第二个 if,否则再次进入第三个 if,继续分配扩容区间,这里第一个判断中的 finishing 也是个细节,后面会讲
- 陆游临安春雨初霁赏析及感悟 临安春雨初霁陆游赏析
- 不足5㎡的卫生间,也有很多需要“操心的事”,建议大家收藏!
- 孕产妇孕期保健 孕妇保健app
- game游戏中心官方 在线游戏网站
- 核舟记翻译文言文 核舟记翻译最简短
- 刀锋意志 手游刀锋意志出装
- 现代养殖业最赚钱行业 哪种养殖业最赚钱
- 火炬之光1技能树 火炬之光技能搭配
- 皇帝成长计划游戏 皇帝成长计划测试版
- 阿里巴巴国际站好做吗? 阿里巴巴国际站怎么做好
特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
