Java集合框架_ HashMap 多线程操作导致死循环问题

在多线程下,进行put操作会导致HashMap死循环,原因在于Hash Map的扩容resize()方法。由于扩容是新建一个数组,复制原数据到数组。由于数组下标挂有链表,但是多线程操作可能导致环形链表。

复制过程如下:

以下模拟2个线程同时扩容,假设当前的空间为2(临界值为1),hashcode分别为0和1,在散列地址0处有元素A和B,这时候要添加C,C经过hash运算得到地址1,这时候由于超过了临界值,空间不够,需要resize方法进行扩容,那么在多线程条件下,会出现条件竞争,模拟过程如下

线程一:读取到当前的Hash Map情况,在准备扩容时,线程二介入读取Hash Map进行扩容

这个过程为,先将 A 复制到新的 hash 表中,然后接着复制 B 到链头(A 的前边:B.next=A),本来 B.next=null, 到此也就结束了(跟线程二一样的过程),但是,由于线程二扩容的原因,将 B.next=A,所以,这里继续复制A,让 A.next=B,由此,环形链表出现:B.next=A; A.next=B

jdk1.8已经解决了死循环问题。

 

posted @ 2019-08-05 22:15  chyblogs  阅读(1297)  评论(0)    收藏  举报