-
JDK1.7HashMap死锁
在看之前可以先看看JDK1.7的Hashmap的源码
HashMap在多线程情况下是不安全的,一个是数据的准确性问题,一个就是可能会出现死锁问题
出现死锁的情况在扩容的代码里,假设现在有两个线程都在对下图的Map进行操作
这个HashMap设置了初始大小为4,负载因子为0.75,现在又添加一个元素D,很不幸通过indexOf方法算出的下标也是在下标0的位置
根据扩容的判断条件if ((size >= threshold) && (null != table[bucketIndex]))
总元素个数为3>=(数组长度4*负载因子0.75)
而且添加的位置不为空,所以进入扩容方法
现在有T1和T2两个线程同时进行添加操作,同时进行扩容
假设T2因为时间片用完轮到T1执行,那么此时T2线程的变量赋值如下,后面的数组就不画了
T1创建新的数组然后将数据转移,完成后T2醒来,如下图所示
注意当T1将数据移动后,数据顺序反了,可以看看上面的代码推理一下,那么假设现在线程T2醒来,继续执行代码
主要代码如下,下面一步代码对比一个图
e.next = newTable[i];
newTable[i] = e;
e = next;
回到循环,判断e不为空,继续执行
Entry<k,v> next = e.next;
然后计算下标,继续代码
e.next = newTable[i];
newTable[i] = e;
e = next;
继续循环,e不为空
Entry<k,v> next = e.next;
e.next = newTable[i];
newTable[i] = e;
e = next;
这里已经出现问题了,两个节点互相引用
__EOF__