sizeCtl的含义

  • 为0: 代表数组没有初始化
  • 为正数:
    • 数组已经初始化,记录的是数组的扩容阈值
    • 如果没有初始化,记录的是数组初始容量
  • 为-1: 代表数组正在初始化中
  • 为负数,并且不是-1: 表示数组正在扩容中

    transfer 扩容

    ```java private final void transfer(Node[] tab, Node[] nextTab) {

    1. int n = tab.length, stride;
    2. if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE)
    3. // stride 每个线程要领多少个任务,也计数要迁移多少个位置
    4. stride = MIN_TRANSFER_STRIDE; // stride肯定大于16
    5. if (nextTab == null) { // initiating
    6. try {
    7. @SuppressWarnings("unchecked")
    8. Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1];
    9. nextTab = nt;
    10. } catch (Throwable ex) { // try to cope with OOME
    11. sizeCtl = Integer.MAX_VALUE;
    12. return;
    13. }
    14. nextTable = nextTab; //创建的新数组(老数组的两倍)
    15. transferIndex = n; //老数组的长度
    16. }
    17. int nextn = nextTab.length; //新数组长度
    18. ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab);
    19. boolean advance = true;
    20. boolean finishing = false; // 所有线程是否完成扩容
    21. for (int i = 0, bound = 0;;) {
    22. Node<K,V> f; int fh;
    23. while (advance) { //计算迁移多少
    24. int nextIndex, nextBound;
    25. if (--i >= bound || finishing)
    26. advance = false;
    27. else if ((nextIndex = transferIndex) <= 0) {
    28. i = -1;
    29. advance = false;
    30. }
    31. else if (U.compareAndSwapInt
    32. (this, TRANSFERINDEX, nextIndex,
    33. nextBound = (nextIndex > stride ?
    34. nextIndex - stride : 0))) { //将transferIndex设置为 老数组的长度-16 或者 0
    35. bound = nextBound; //老数组的长度-16 或者 0
    36. i = nextIndex - 1; //老数组的长度-1
    37. advance = false; //结束当次循环
    38. }
    39. }
    40. if (i < 0 || i >= n || i + n >= nextn) { //判断是否扩容完成
    41. int sc;
    42. if (finishing) {
    43. nextTable = null;
    44. table = nextTab;
    45. sizeCtl = (n << 1) - (n >>> 1);
    46. return;
    47. }
    48. if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, sc - 1)) { //判断所有线程是否完成扩容
    49. if ((sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT)
    50. return;
    51. finishing = advance = true;
    52. i = n; // recheck before commit
    53. }
    54. }
    55. else if ((f = tabAt(tab, i)) == null) //如果当前位置为空 那么赋值fwd
    56. advance = casTabAt(tab, i, null, fwd);
    57. else if ((fh = f.hash) == MOVED) //如果已经迁移完成了 那么什么都不干
    58. advance = true; // already processed
    59. else {
    60. synchronized (f) { //防止迁移的时候 别的线程加数据
    61. if (tabAt(tab, i) == f) {
    62. Node<K,V> ln, hn;
    63. if (fh >= 0) {
    64. int runBit = fh & n;
    65. Node<K,V> lastRun = f;
    66. //区别数据 假设现在迁移的位置 是个链表 size是6 那么可能还是3个保留在原来的位置 还有3个放置到原来的位置+老数组的长度位置上
    67. for (Node<K,V> p = f.next; p != null; p = p.next) {
    68. int b = p.hash & n;
    69. if (b != runBit) {
    70. runBit = b;
    71. lastRun = p;
    72. }
    73. }
    74. if (runBit == 0) {
    75. ln = lastRun;
    76. hn = null;
    77. }
    78. else {
    79. hn = lastRun;
    80. ln = null;
    81. }
    82. for (Node<K,V> p = f; p != lastRun; p = p.next) {
    83. int ph = p.hash; K pk = p.key; V pv = p.val;
    84. if ((ph & n) == 0)
    85. ln = new Node<K,V>(ph, pk, pv, ln);
    86. else
    87. hn = new Node<K,V>(ph, pk, pv, hn);
    88. }
    89. setTabAt(nextTab, i, ln);
    90. setTabAt(nextTab, i + n, hn);
    91. setTabAt(tab, i, fwd);
    92. advance = true;
    93. }
    94. else if (f instanceof TreeBin) {
    95. TreeBin<K,V> t = (TreeBin<K,V>)f;
    96. TreeNode<K,V> lo = null, loTail = null;
    97. TreeNode<K,V> hi = null, hiTail = null;
    98. int lc = 0, hc = 0;
    99. for (Node<K,V> e = t.first; e != null; e = e.next) {
    100. int h = e.hash;
    101. TreeNode<K,V> p = new TreeNode<K,V>
    102. (h, e.key, e.val, null, null);
    103. if ((h & n) == 0) {
    104. if ((p.prev = loTail) == null)
    105. lo = p;
    106. else
    107. loTail.next = p;
    108. loTail = p;
    109. ++lc;
    110. }
    111. else {
    112. if ((p.prev = hiTail) == null)
    113. hi = p;
    114. else
    115. hiTail.next = p;
    116. hiTail = p;
    117. ++hc;
    118. }
    119. }
    120. ln = (lc <= UNTREEIFY_THRESHOLD) ? untreeify(lo) :
    121. (hc != 0) ? new TreeBin<K,V>(lo) : t;
    122. hn = (hc <= UNTREEIFY_THRESHOLD) ? untreeify(hi) :
    123. (lc != 0) ? new TreeBin<K,V>(hi) : t;
    124. setTabAt(nextTab, i, ln);
    125. setTabAt(nextTab, i + n, hn);
    126. setTabAt(tab, i, fwd);
    127. advance = true;
    128. }
    129. }
    130. }
    131. }
    132. }

    }

  1. (resizeStamp(n) << RESIZE_STAMP_SHIFT) + 2)
  2. (sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT

```