JDK1.8之后,HashMap头插法改为尾插法?

1.头插法在并发下有致命问题,就是可能形成数据环,get 数据时死循环,而在 1.8 之前因为处理 hash 冲突的方式是用链表存放数据,使用头插法可以提升一定效率。

但是在 1.8 之后这个效率提升就可有可无了,链表长度超过 7 就要考虑升级红黑树了,所以哪怕进行尾插遍历次数也会很有限,效率影响不大。

2.就是因为 1.8 之后数据结构的变动,当链表长度达到阈值,升级为红黑树后头插法就不适用了,因为构建红黑树需要进行比对更新序列,也就不能去说是头插法还是尾插了

发表评论

后才能评论

评论(3)

  • 一蓑烟雨 普通 2022-09-28 4:30 下午

    1.8 之前,尾插法会遍历整个链表效率低,因此采用头插法,但是头插法在并发下会导致死循环。

    1.8后,考虑到,当链表长度过长的时候,查询链表中的一个元素就比较耗时,这时就引入了红黑树,HashMap的结构从“数组+链表”变成“数组+链表/红黑树”,当链表上的元素个数超过 8 个并且数组长度 >= 64 时自动转化成红黑树, 因此采用尾插法遍历次数也会很有限,效率影响不大。

  • Q_Uattro 普通 2022-04-04 9:15 下午

    为什么头插法会导致死循环:
    JDK1.7采用的头插法,即新加的元素在链表的头部,这样减少了遍历获取尾节点的性能消耗,但多线程并发插入同一个元素的情况,由于是头插法,所以再设置为头节点的时候,另一个线程该节点已经设置成功头节点了,那当前线程这个头节点的下一节点指向的就也是自己的引用了,这样的链表当调用map.get的时候,需要遍历链表数据的时候,由于下一节点一直指向的是自己,导致死循环