HashMap为什么会死锁
因为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在多线程环境下并不安全的主要原因:多线程操作时会导致数据的不一致。下面进行详细解释。一、HashMap的数据结构问题 HashMap基于哈希表实现,通过键值对的存储方式提供高效的查找性能。但在多线程环境下,多个线程可能同时修改HashMap的内部结构,这种情况下可能导致数据冲突和不一致,从而出现数据错误...
hashmap为什么是线程不安全的
2、JDK1.8 中,由于多线程对HashMap进行put操作,调用了HashMap,假设两个线程A、B都在进行put操作,并且hash函数计算出的插入下标是相同的,当线程A执行完第六行代码后由于时间片耗尽导致被挂起,而线程B得到时间片后在该下标处插入了元素,完成了正常的插入,然后线程A获得时间片,由于之前已经进行了...
HashMap为什么不安全?
1.Map概述 我们都知道HashMap是线程不安全的,但是HashMap的使用频率在所有map中确实属于比较高的。因为它可以满足我们大多数的场景了。 Map类继承图 复制代码 Map是一个接口,我们常用的实现类...
HashMap为什么不安全?
我们都知道HashMap是线程不安全的,在多线程环境中不建议使用,但是其线程不安全主要体现在什么地方呢,本文将对该问题进行解密。 1.jdk1.7中的HashMap 在jdk1.8中对HashMap做了很多优化,这里先分析在jdk1.7中的问题,相信大家都知道在jdk1.7多线程环境下HashMap容易出现死循环,这里我们先用代码来模拟出现死循环的情况:...
hashmap为什么线程不安全
hashmap在jdk1.7多线程环境下HashMap容易出现死循环所以线程不安全。hashmap是基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此实现假定哈希函数将元素适当地分布在各桶之间,可为基本操作(get和put)提供稳定的性能。迭代collection视图所需的时间与HashMap实例的...
hashmap 为什么线程不安全
HashMap底层是一个Entry数组,当发生hash冲突的时候,hashmap是采用链表的方式来解决的,在对应的数组位置存放链表的头结点。对链表而言,新加入的节点会从头结点加入。javadoc中关于hashmap的一段描述如下:此实现不是同步的。如果多个线程同时访问一个哈希映射,而其中至少一个线程从结构上修改了该映射,...
java 为什么使用hashmap
(3)引入 Hash 算法又导致了 Hash 冲突。为了解决 Hash 冲突,HashMap 采用链地址法,在冲突位置转为使用链表存储。(4)链表存储过多的节点又导致了在链表上节点的查找性能的恶化。为了优化查找性能,HashMap 在链表长度超过 8 之后转而将链表转变成红黑树,以将 O(n) 复杂度的查找效率提升至 O(...
HashMap为什么会死锁
因为HashMap是非线程安全的,所以死锁一般发生在并发的情况下。举个栗子 :我们假设有二个线程T1、T2,HashMap容量为2 首先T1线程放入key A、B、C、D、E。在T1线程中A、B、C Hash值相同,于是形成一个链接,假设为A->C->B,而D、E Hash值不同,于是容量不足,需要新建一个更大尺寸的hash表,...
hashmap为什么要hash两次
hash算法不是为了避免重复,而是加快访问速度。使用hash算法就是为了减少查找数据时,比较的次数;查找时最理想的情况下,仅需一次比较就能找到,当然这种理想是以牺牲存储空间实现的。实际应用中不可取,但是由此我们可以看出hash在查找方面的高效性;
HashMap是什么东西
HashMap,中文名哈希映射,HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。HashMap数组每一个元素的初始值都是Null。HashMap是基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用...
资炒复方: 递归死循环肯定是中止条件错了!看了你的代码while (i
新余市15042122793: hashmap多线程为什么造成死循环 - ?
资炒复方: 一直以来只是知道HashMap是线程不安全的,但是到底HashMap为什么线程不安全,多线程并发的时候在什么情况下可能出现问题? HashMap底层是一个Entry数组,当发生hash冲突的时候,hashmap是采用链表的方式来解决的,在对应的数组位置存放链表的头
新余市15042122793: java怎么避免死锁 - ?
资炒复方: 解决方式:1、尽量使用tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),设置超时时间,超时可以退出防止死锁.2、尽量使用java.util.concurrent(jdk 1.5以上)包的并发类代替手写控制并发,比较常...
新余市15042122793: 数据库表死锁是如何造成的?如何避免(解决)死锁? - ?
资炒复方: 独占方式把开表 然后没有关闭表或关闭数据库连接会造成死锁 独占方式打开表主要有 开启事务操作 避免方法是:良好编程习惯 ,即打开表后应及时关闭或撤毁资源, 提交或回滚事务 解决死锁:我知道的方法是重启数据库
新余市15042122793: 数据库中死锁是什么产生的? - ?
资炒复方: 数据库操作的死锁是不可避免的,本文并不打算讨论死锁如何产生,重点在于解决死锁,通过SQL Server 2005, 现在似乎有了一种新的解决办法. 将下面的SQL语句放在两个不同的连接里面,并且在5秒内同时执行,将会发生死锁. use ...
新余市15042122793: mysql 存储过程出现死锁 - ?
资炒复方: 产生死锁的四个必要条件: (1) 互斥条件:一个资源每次只能被一个进程使用. (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放. (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺. (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系. 这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之 一不满足,就不会发生死锁.
新余市15042122793: 试述死锁产生的原因和解决办法 - ?
资炒复方: 产生原因1、竞争资源引起进程死锁 当系统中供多个进程共享的资源如打印机、公用队列的等,其数目不足以满足诸进程的需要时,会引起诸进程对资源的竞争而产生死锁. 2、可剥夺资源和不可剥夺资源 系统中的资源可以分为两类,一类是...
新余市15042122793: 数据库死锁的基本解释 - ?
资炒复方: 每个使用关系型数据库的程序都可能遇到数据死锁 的情况.理解什么是死锁之前先要了解锁定的概念:多数情况下,可以认为如果一个资源被锁定,它总会在以后某个时间被释放.而死锁发生在当多个进程访问同一数据库时,其中每个进程拥有的锁都是其他进程所需的,由此造成每个进程都无法继续下去.简单的说,进程A等待进程B释放他的资源,B又等待A释放他的资源,这样就互相等待就形成死锁.
新余市15042122793: hashmap为什么线程不安全 - ?
资炒复方: HashMap底层是一个Entry数组,当发生hash冲突的时候,hashmap是采用链表的方式来解决的,在对应的数组位置存放链表的头结点.对链表而言,新加入的节点会从头结点加入.javadoc中关于hashmap的一段描述如下:此实现不是同步的....
新余市15042122793: Java中的HashMap的工作原理是什么? - ?
资炒复方: 一,存储方式: Java中的HashMap是以键值对(key-value)的形式存储元素的.二,调用原理: HashMap需要一个hash函数,它使用hashCode()和equals()方法来向集合/从集合添加和检索元素.当调用put()方法的时候,HashMap会...