结论:
1.多线程情况下会进行多次扩容,第一次扩容后e与其next位置已经互换,第二次扩容的时候将e放在新的hashmap中后,取next
代码实现如下,注意最后三行
具体分析
对于场景如下,两个线程同时需要扩容,线程2阻塞,线程1先进行。
之后hashmap状态如下
此时线程2苏醒,再次执行扩容
①开始扩容从e2开始,将e2放在新链表上
此时需要获取新的next,即新hashmap中的3是e.next,而3就是next。此时出现问题,本来next需要在原表上,此时却在新表上了。再进行节点移动
这是又移动一次之后,因为需要e= next,所以e此时为3.
第三轮将e.next = newTable[i] 时,出现环状
宏观来说是应该头插法,从头出发,但是多线程会出现后面的节点先出发的情况导致next乱掉了,在新表中,关键操作e = next 和e.next = Table[i]。
参考资料: