HashMap1.7和1.8中多线程下的问题

前言:今日在做总结HashMap1.7和1.8对比时,在多线程下会呈现不同的问题,总结如下

首先HashMap1.7和1.8在多线程下的一个共同的问题-数据错乱

我们都知道HashMap并不是线程安全的
在这里做一个测试:在这里插入图片描述
说明:启用两个线程,都执行hashmap的put方法,并且加入的对象所对应的hash值相同都为1,首先线程1去执行put方法,在确定索引1的位置并没有其他元素,准备新建一个node时,这时切换到线程2去执行put方法,并且在同时,线程2准备put插入的key的值对应的索引也为1,且同样没有其他元素,并且新建了node并返回,此时又切换到线程1继续执行,则会将线程2已经加入的key="1"覆盖掉,最终在索引为1的位置只会留下key=a.即发生了数据错乱的现象.

HashMap1.7多线程下会产生扩容死链的问题.

首先要清楚1.7下扩容的一个流程,首先假设a,b都在同一个链表上面,e所指向的就是打算加入到扩容后的数组中的元素,next指向的是下一个元素, 在执行扩容后,e就会先将所指向的元素a头插法插入到新的数组中,接着next指向下一个元素,即null,e指向下一个元素b,接着将b通过头插法加入到扩容后的数组中.接着e指向null,第三轮循环开始发现e已经是nul了则会退出循环, 这样就完成了链表的迁移.
在这里插入图片描述
需要注意的是,在迁移后这个对象还是原来的对象,并没有对象新的创建
假设在两个线程下都要进行扩容
在这里插入图片描述
在线程1的临时变量e和next刚引用了这两个节点还未来得及移动节点,发生了线程切换,由线程2完成了数组的扩容,由于头插法,链表的顺序是颠倒的,但线程1的临时变量e和next还在引用这两个节点.在这里插入图片描述
此时线程1扩容结束后,继续线程1的进行,首先第一轮:线程1的e指向的是元素a,next指向b元素,那么在a的扩容的数组索引为1的位置就会通过头插法插入a,即1->a, 第二轮:接着next指向a,e指向b。在索引为1的的位置通过头插法就会插入b,即 1->b-> a,第三轮:e指向a,next指向null,通过头插法在索引为1的位置插入a,即1->a->b->a,a是通一个对象,即1 ->a<->b,这样在检索索引为1的链表元素时就会造成死循环,即扩容死锁的问题.
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有梦想的小何

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值