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

来源:互联网 发布:tomcat修改端口号 编辑:程序博客网 时间:2024/06/05 09:43

众所周知,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
原创粉丝点击