HashMap为啥会死锁

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HashMap为啥会死锁相关的知识,希望对你有一定的参考价值。

参考技术A

因为HashMap是非线程安全的,所以死锁一般发生在并发的情况下。

举个栗子 :

我们假设有二个线程T1、T2,HashMap容量为2

首先T1线程放入key A、B、C、D、E。在T1线程中A、B、C Hash值相同,于是形成一个链接,假设为A->C->B,而D、E Hash值不同,于是容量不足,需要新建一个更大尺寸的hash表,然后把数据从老的Hash表中 迁移到新的Hash表中(refresh)。这时T2线程闯进来了,T1暂时挂起,T2线程也准备放入新的key,这时也 发现容量不足,也refresh一把。refresh之后原来的链表结构假设为C->A,之后T1线程继续执行,链接结构 为A->C,这时就形成A.next=B,B.next=A的环形链表,并且这里并不会报错和出现异常,只有当使用get来进行取值的时候进入这个环形链表就陷入了死循环。

其实,关键就在于rehash过程。在前面我们说了后续调用 HashMap 的get()方法才会造成死锁。既然是 get()造成的死锁 ,一定是跟put()进去元素的位置有关,所以我们从 put()方法开始看起。

看到最后这个 函数transfer() ,就算找到了问题的关键:
我们会发现转移的时候是逆序的。假如转移前链表顺序是1->2->3,那么转移后就会变成3->2->1。这时候就有点头绪了,死锁问题不就是因为1->2的同时2->1造成的吗?所以,HashMap 的死锁问题就出在这个transfer()函数上。



并且个人认为,这不算是死锁,毕竟原因是因为进入了回环链表。死锁是两个线程互相等待对方释放锁才对。。。。。

参考自博客:
https://blog.csdn.net/u010988549/article/details/104815268

以上是关于HashMap为啥会死锁的主要内容,如果未能解决你的问题,请参考以下文章

什么是hashMap,初始长度,高并发死锁,java8 hashMap做的性能提升

构建一个hashmap死锁的DEMO

为啥面试要问hashmap 的原理

如果在检查使用 hashmap 解决 Leetcode 二和的解决方案之前执行 map.put,为啥会失败?

Rehash死锁的问题

021 HashMap 和 Hashtable 有什么区别?