1.8之前的HashMap线程不安全,包含循环链表的问题,get()时候会造成死循环cpu爆满。原因是1.8之前采用的头插法;1.8之后采用尾插法。

1.8 resize()

  1. final Node<K,V>[] resize() {
  2. Node<K,V>[] oldTab = table;
  3. int oldCap = (oldTab == null) ? 0 : oldTab.length;
  4. int oldThr = threshold;
  5. int newCap, newThr = 0;
  6. if (oldCap > 0) {
  7. if (oldCap >= MAXIMUM_CAPACITY) {
  8. threshold = Integer.MAX_VALUE;
  9. return oldTab;
  10. }
  11. // 新容器size扩大一倍
  12. else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
  13. oldCap >= DEFAULT_INITIAL_CAPACITY)
  14. // 阈值也扩大一倍
  15. newThr = oldThr << 1; // double threshold
  16. }
  17. else if (oldThr > 0) // initial capacity was placed in threshold
  18. newCap = oldThr;
  19. else { // zero initial threshold signifies using defaults
  20. newCap = DEFAULT_INITIAL_CAPACITY;
  21. newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
  22. }
  23. if (newThr == 0) {
  24. float ft = (float)newCap * loadFactor;
  25. newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
  26. (int)ft : Integer.MAX_VALUE);
  27. }
  28. threshold = newThr;
  29. @SuppressWarnings({"rawtypes","unchecked"})
  30. // 开启一个新数组,size为原来两倍
  31. Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
  32. // 指向新的table
  33. table = newTab;
  34. if (oldTab != null) {
  35. // 遍历老的数组
  36. for (int j = 0; j < oldCap; ++j) {
  37. Node<K,V> e;
  38. // 遍历元素链表
  39. if ((e = oldTab[j]) != null) {
  40. oldTab[j] = null;
  41. if (e.next == null)
  42. // 单节点直接用&定位,容量是1000 变成 10000,则&之后要么在原来位置,要么是原来位置*2
  43. newTab[e.hash & (newCap - 1)] = e;
  44. else if (e instanceof TreeNode)
  45. // 如果改节点已经变成一颗树了,在树中插入
  46. ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
  47. else { // preserve order
  48. // 新表size是原来一倍,所以出现高位和低位,所以拆出来两条链表了,每个链表都维护头和尾
  49. Node<K,V> loHead = null, loTail = null;
  50. Node<K,V> hiHead = null, hiTail = null;
  51. Node<K,V> next;
  52. do {
  53. next = e.next;
  54. if ((e.hash & oldCap) == 0) {
  55. if (loTail == null)
  56. loHead = e;
  57. else
  58. loTail.next = e;
  59. loTail = e;
  60. }
  61. else {
  62. if (hiTail == null)
  63. hiHead = e;
  64. else
  65. hiTail.next = e;
  66. hiTail = e;
  67. }
  68. } while ((e = next) != null);
  69. if (loTail != null) {
  70. loTail.next = null;
  71. newTab[j] = loHead;
  72. }
  73. if (hiTail != null) {
  74. hiTail.next = null;
  75. newTab[j + oldCap] = hiHead;
  76. }
  77. }
  78. }
  79. }
  80. }
  81. return newTab;
  82. }