发生在 put 中,因为此时已经获得了锁,因此 rehash 时不需要考虑线程安全

    1. private void rehash(HashEntry<K,V> node) {
    2. HashEntry<K,V>[] oldTable = table;
    3. int oldCapacity = oldTable.length;
    4. int newCapacity = oldCapacity << 1;
    5. threshold = (int)(newCapacity * loadFactor);
    6. HashEntry<K,V>[] newTable =
    7. (HashEntry<K,V>[]) new HashEntry[newCapacity];
    8. int sizeMask = newCapacity - 1;
    9. for (int i = 0; i < oldCapacity ; i++) {
    10. HashEntry<K,V> e = oldTable[i];
    11. if (e != null) {
    12. HashEntry<K,V> next = e.next;
    13. int idx = e.hash & sizeMask;
    14. if (next == null) // Single node on list
    15. newTable[idx] = e;
    16. else { // Reuse consecutive sequence at same slot
    17. HashEntry<K,V> lastRun = e;
    18. int lastIdx = idx;
    19. // 过一遍链表, 尽可能把 rehash 后 idx 不变的节点重用
    20. for (HashEntry<K,V> last = next;
    21. last != null;
    22. last = last.next) {
    23. int k = last.hash & sizeMask;
    24. if (k != lastIdx) {
    25. lastIdx = k;
    26. lastRun = last;
    27. }
    28. }
    29. newTable[lastIdx] = lastRun;
    30. // 剩余节点需要新建
    31. for (HashEntry<K,V> p = e; p != lastRun; p = p.next) {
    32. V v = p.value;
    33. int h = p.hash;
    34. int k = h & sizeMask;
    35. HashEntry<K,V> n = newTable[k];
    36. newTable[k] = new HashEntry<K,V>(h, p.key, v, n);
    37. }
    38. }
    39. }
    40. }
    41. // 扩容完成, 才加入新的节点
    42. int nodeIndex = node.hash & sizeMask; // add the new node
    43. node.setNext(newTable[nodeIndex]);
    44. newTable[nodeIndex] = node;
    45. // 替换为新的 HashEntry table
    46. table = newTable;
    47. }