HashMap头插法会导致死循环问题
大家天天都说Java1.7Hashmap头插法会导致死循环问题 可是大家知道为什么嘛?
下面我们来详细讲解一下全过程:
首先hashmap头插法导致死循环问题是在多线程并发环境下 2个线程并发扩容
而且旧的链表扩容到新的链表的数组是相同的情况下会导致死循环问题。
比如
要弄清除原理 首先我们需要看懂扩容的过程
上源码,标注了主要的序号
头插法单个线程进行扩容
下面步骤我们都标了序号
第一步 首先找到第一个头
2.
3.
4.
第二次循环
1.
2.
3.
4.
继续循环会扩容完成
多个线程并发扩容导致死循环
这个时候有一个场景比如我一个线程AB同时扩容
都执行到这个方法的时候 这个图是这样的 ,
如果A已经扩容完成 是这样的
因为线程AB中的123地址是相同的
所以对应线程A中的指针为
这个时候B继续扩容
方法2
方法3
4.
下一次循环
执行1
2.是将e.next=newTable[i] 也就是2指向1 其实已经指向了所以和上面的图一样
4.
再进一次循环
1.next等于null了
2.
最核心的一步来了
这个时候就会导致死循环
一开始会很懵 跟着画图走几遍就懂了
虽然尾插法会解决死循环的问题,但是多线程情况下还是会导致数据丢失的问题, 建议多线程环境下使用线程安全的concurrentHashmap