1.15 HashMap多线程操作导致死循环问题及其在JDK1.8中的优化

本文详细分析了在JDK1.8之前,HashMap多线程操作可能导致的死循环问题,以及JDK1.8通过尾插法优化解决此问题的原理。讨论了hashCode的扰动函数改进和复制链表时如何避免死循环,重点解释了如何通过判断hash值来确定元素在新旧数组中的位置,以提高并发安全性。
摘要由CSDN通过智能技术生成

1.15 HashMap多线程操作导致死循环问题及其在JDK1.8中的优化

JDK1.8之前,如果多个线程使用同一个HashMap,可能会出现多个线程同时对HashMap进行扩容的场景,而扩容是新建一个数组,将链表中的元素从头结点遍历过去,每个进行rehash(因为每个key在数组长度变化后,hash会变化),再放到新数组里,最后引用新数组;
有一种情况会出现死循环:
拿旧数组上某个链表上的两个连续结点A->B举例,假设A、B依次被线程1拿到了新数组(假设仍在同一个桶中),成了B->A的顺序;这时,线程2也对HashMap进行扩容,再次将A往新数组对应位置的链头添加,也就是A->next=头结点(也就是B),这时B的next因为线程一指向A,而A的next因为线程二指向B,即B->A->B,产生了循环;

另:JDK1.8解决了死循环问题;
这个问题是头插法造成的,所以1.8进行了优化,改为了尾插法;

铺垫:
1.8之前,key的hashCode要进行hash扰动函数计算hash值;
hash():hashCode右位移了四次再异或,来增强随机性;
—>
得到的hash与数组长度2n按位与&取模:
(2n-1)&hash为什么可以取模:
2 n用二进制表示必定为高位为1,低位全是0(10000…0的

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值