HashMap多线程的问题
扩容 —— Resize
HashMap的容量是有限的。当经过多次元素插入,使得HashMap达到一定饱和度时,Key映射位置发生冲突的几率会逐渐提高。
这个时候就需要进行扩容,就是Resize。
衡量HashMap是否要进行Resize的条件:
HashMap.Size >= Capacity * LoadFactor
Capacity是当前HashMap的当前长度,LoadFactor是负载因子。
Resize进行了2件事情
- 扩容
- ReHash 遍历原Entry数组,把所有的Entry重新Hash到新数组。
问题
Hashmap不是线程安全的。在高并发环境下做插入操作,有可能出现下面的环形链表:
延伸思考
如何判断链表有环?
采用“快慢指针”的方法,就是有两个指针fast和slow,开始的时候两个指针都指向链表头head,然后在每一步
操作中slow向前走一步即:slow = slow->next,而fast每一步向前两步即:fast = fast->next->next。
由于fast要比slow移动的快,如果有环,fast一定会先进入环,而slow后进入环。当两个指针都进入环之后,经过一定步的操作之后
二者一定能够在环上相遇,并且此时slow还没有绕环一圈,也就是说一定是在slow走完第一圈之前相遇。