HashMap为什么是线程不安全的?

1.多线程下进行put操作的时候导致的数据不一致。
当有多个线程进行put操作时,第一个线程已经计算完放值的桶索引坐标,此时轮到第二个线程,第二个线程成功地把记录插入到桶里面,然而两个线程计算出来的桶索引是一样的,然后第一个线程就会继续往原先的桶索引插值,就覆盖了第二个线程的记录。

2.可能因为resize(扩容)而引起死循环。

HashMap的扩容机制就是重新申请一个容量是当前的2倍的桶数组,然后将原先的记录逐个重新映射到新的桶里面,然后将原先的桶逐个置为null使得引用失效。HashMap之所以线程不安全,就是resize这里出的问题。


 

HashMap为什么是线程不安全的?

resize的时候链表会反转,原先1->2->3,resize之后3->2->1。假设有A,B两个线程, 线程A执行到了transfer方法的Entry next = e.next这一句 ,此时状态是1->2,然后轮到线程B,线程B顺利完成resize操作,此时3->2->1。然后又到A线程,因为链表已经被线程B变成3->2->1,所以线程A会进入1->2->1的环形链表,从而导致死循环。