welcome to my blog
问题描述: 并发情况下, hashmap在扩容时使用头插法可能出现循环链表, 后果就是调用get()方法时可能陷入死循环. 为什么会出现循环链表呢?
产生循环链表的过程:
如下所示的hashmap, 有两个元素, 它们的key分别是1和3, 假设再增加一个元素时会触发扩容操作
此时线程1和线程2都执行put()操作, 便都会触发hashmap的扩容操作,
假设线程1扩容时, 执行完transfer()中的Entry<K,V> next = e.next;
被挂起, 此时e指向1, next指向3, 如下图所示
假设1和3在新的数组中仍然发生哈希碰撞, 假设线程2完成了扩容, 那么此时哈希表的样子如下图所示
可以发现, 由于使用了头插法, 所以3变成了头结点
回到线程1, e指向的是1, next指向的是3, 继续向下执行
当执行完e.next = newTable[i];</