HashMap 死循环问题是 JDK1.7 之前存在问题,主要 * 源于 HashMap 的自身的工作机制和并发处理 导致 * 的问题,而对于 JDK1.8 后,官方就彻底解决了这个问题,对于死循环问题,我们首先了解一下HashMap 数据插入原理
JDK1.7的HashMap头插法
在
Java
的
HashMap
中,
put()
操作采用的是
“
头插法
”
,也就是
把新元素插入到链表头部
。如有相同的key值插入,会覆盖旧元素。如果新元素的
key
值在
HashMap
中不存在,则会新建一个节点并放在链表头部。如果此时桶数组中对应位置已经有了元素,那么新插入的元素会作为该元素的前驱。这样子会导
致链表顺序的倒转,有成环风险
导致死循环的原因
阶段一:
多线程下多个线程同时在扩容临界点进行插入操作,同时开始进行扩容
阶段二:
多个线程同时进行扩容,扩容前首先需要获取结尾元素的下一个节点信息,以便使用头插法进行扩
容。然后有部分线程时间片用完,在获取节点信息后就就行休眠了,还没开始进行头插扩容。有部分线
程直接进行扩容操作,在扩容操作过程种的节点结构重组消息休眠线程不知道。
阶段三:
第二阶段进行扩容操作后,节点结构重组后,休眠的线程拿着旧的节点消息进行二次头插,致使死循
环