if (i < 0 || i >= n || i + n >= nextn) {int sc;if (finishing) {nextTable = null;table = nextTab;sizeCtl = (n << 1) - (n >>> 1);return;}if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, sc - 1)) {if ((sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT)return;finishing = advance = true;i = n; // recheck before commit}}else if ((f = tabAt(tab, i)) == null)advance = casTabAt(tab, i, null, fwd);else if ((fh = f.hash) == MOVED)advance = true; // already processedelse {synchronized (f) {if (tabAt(tab, i) == f) {省略 。。。}}}接下来有 4 个 if 判断,第一个 if,当扩容完毕时 i 才会小于 0,第二个 if,如果目标索引位的值为 null,通过 CAS 设置为 ForwardingNode
static final class ForwardingNode<K,V> extends Node<K,V> {final Node<K,V>[] nextTable;ForwardingNode(Node<K,V>[] tab) {super(MOVED, null, null, null);this.nextTable = tab;}}ForwardingNode 是对 Node 的一个简单封装,hash 值是-1,表示正在扩容,nextTable 指向扩容之后的数组对象
第三个 if,如果发现节点 hash 值为-1,那么继续,这里,大家想过没有,什么时候会执行到这个分支呢,从上面的 while 循环可以发现,每个线程都负责有自己的扩容区间,是不会走到其他线程的区间的,那这个 if 判断是干嘛的呢?读者可以先思考一下,后面会提到

文章插图
如果节点不为空,会将节点的值转移到新的数组上去,看过 HashMap 扩容源码的话,这块理解起来就会很容易了,我们计算 key 在数组中下标位是通过 hash&(n-1)来计算的,当数组扩容后,hash 是不变的 ,变得只是 n-1,举个例子,n=8,扩容之后 n=16,转换成二进制
- 8-1: 00000111
- 16-1: 00001111
- 8:00001000
- 1->2->3->4->5->6->null
当所有的数据都完成迁移后,i 会变成-1,来到这个 if
if (i < 0 || i >= n || i + n >= nextn) {int sc;if (finishing) {nextTable = null;table = nextTab;sizeCtl = (n << 1) - (n >>> 1);return;}if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, sc - 1)) {if ((sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT)return;finishing = advance = true;i = n; // recheck before commit}}刚进入的时候,finishing 是 false,进入第二个 if,因为自己的扩容任务结束了,所以要把 sizeCtl 减 1,当然也是通过 CAS 的,如果失败了,重新进入循环再试一次,里面那个 if 判断应该不陌生了吧,还记得我们一开始赋值的时候吗,这个就是判断此时线程是否是最后一个执行扩容的线程,如果不是,退出方法,没你事了,否则,finishing 设为 true,i=n,看到这里会不会觉得奇怪,i 怎么又等于 n 了呢,没错,从头到尾再检查一遍,还记得一开始 while 里说的那个 finishing 条件吗,如果没有这个条件,那么最后一个线程只会检查自己边界 bound 到 n 的区间,但是有了这个条件,则会把所有区间都检查一遍
- 陆游临安春雨初霁赏析及感悟 临安春雨初霁陆游赏析
- 不足5㎡的卫生间,也有很多需要“操心的事”,建议大家收藏!
- 孕产妇孕期保健 孕妇保健app
- game游戏中心官方 在线游戏网站
- 核舟记翻译文言文 核舟记翻译最简短
- 刀锋意志 手游刀锋意志出装
- 现代养殖业最赚钱行业 哪种养殖业最赚钱
- 火炬之光1技能树 火炬之光技能搭配
- 皇帝成长计划游戏 皇帝成长计划测试版
- 阿里巴巴国际站好做吗? 阿里巴巴国际站怎么做好
特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
