HashMap在非线程安全下的死循环

众所周知,HashMap是非线程安全的,需要线程安全一般选择ConcurrentHashMap或者Hashtable,但是往往常识性的东西容易出问题,比如最近有个同事在线上就碰到这个问题,以前也知道HashMap的这问题,但是最近放假,花点时间整理下:

  • 觉得画图耗费时间,就直接手绘再上传照片,下面直接对着下面的图说明下
  • *

图一

1、HashMap基础数据结构是一个链表数组,假设hash方式是模2,对于余数为1上7、11、13三个node点。

这里写图片描述
图二

2、若有thread1和thread2两个线程同时进行rehash,在图二是resize的transfer方法,当thread1在593-599之间发生阻塞,thread2执行并进行rehash,此时thread1和thread2的状态如图一的rehash状态所示,thread1的e=7,next=11。当thread2进行rehash会导致数组上的链表反转顺序为11->7->null。
3、之后block的thread1唤醒,继续之前的rehash,经过两轮循环,链表反转顺序为11->7->null,与thread2的rehash的结果不同的是,thread2中的11的next为null,但是thread1的11的next为7(由于table中的元素e是共享变量),这就是导致死循环的缘由。当进入第三轮循环时,死循环产生。

简单总结,HashMap非线程安全的死循环原因有,rehash时链表反转,table中的元素e是共享变量。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值