由于 HashMap 的容量是有限的,如果 HashMap 中的数组的容量很小,假如只有 2 个,那么如果要放进 10 个 keys 的话,碰撞就会非常频繁,此时一个 O(1) 的查找算法,就变成了链表遍历,性能变成了 O(n),这是 Hash 表的缺陷。
为了解决这个问题,HashMap 设计了一个阈值,其值为容量的 0.75,当 HashMap 所用容量超过了阈值后,就会自动扩充其容量。
在多线程的情况下,当重新调整 HashMap 大小的时候,就会存在条件竞争,因为如果两个线程都发现 HashMap 需要重新调整大小了,它们会同时试着调整大小。在调整大小的过程中,存储在链表中的元素的次序会反过来,因为移动到新的 bucket 位置的时候,HashMap 并不会将元素放在链表的尾部,而是放在头部,这是为了避免尾部遍历。如果条件竞争发生了,那么就会产生死循环了。