并发下HashMap头插会造成死循环情况说明

说明:

JDK1.8之前HashMap触发扩容机制时,会创建新的Entry[ ]数组,将旧的Entry数据进行复制,当某个entry上具有链式结构时,采用头插方式进行数据迁移,即将旧链表数据从头部遍历,每次取到的数据插入到新链表的头部。 但并发下会产生死循环,JDK1.8改用尾插方法。


并发头插死循环问题:

比如有两个线程同时对该HashMap进行rehash,要将链表进行重新排列 rehash前链表结构为:A --> B -->C

  1. 线程1进行操作:遍历原链表,首先获得节点A及A.next = B,操作挂起,线程2进入。(线程1仅获取到了数据A及next,并未进行其他操作)
  2. 线程2进行操作:遍历原链表,以头插方式遍历执行,执行完成 B – > A。
  3. 线程1继续执行:遍历原链表,头插方式执行,完成 B – > A,此时线程2数据提交,线程1发现 B.next 不为null,继续遍历执行,又将B.next = A插入,形成A --> B – > A循环结构。

JDK1.8尾插为什么会避免这个问题,因为尾插每次操作,结点顺序都保持不变,自己画一下就知道了。

经验分享 程序员 微信小程序 职场和发展