作者:这个昵称能用嘛 | 来源:互联网 | 2023-06-05 14:36
hashmap死循环,hashmap并发死循环原理00-1010预备知识无限循环执行步骤1无限循环执行步骤2无限循环执行步骤3解决方案总结前言:HashMap无限循环是一个常见且经
hashmap 死循环,hashmap并发死循环原理
00-1010预备知识无限循环执行步骤1无限循环执行步骤2无限循环执行步骤3解决方案总结前言:
HashMap无限循环是一个常见且经典的问题,在日常采访中经常出现,下面我们就通过图解的方式带大家彻底了解无限循环产生的原因。
00-1010 JDK 1.7版本出现了无限循环问题,主要是HashMap本身的运行机制和并发操作导致了无限循环。在JDK 1.7中,HashMap的底层数据实现是数组链表,
如下图所示:
而 HashMap 在数据添加时使用的是头插入,如下图所示:
HashMap 正常情况下的扩容实现如下图所示:
旧散列表的节点将依次转移到新散列表中。旧HashMap传递的顺序是A,B,C,而新HashMap使用的是head插入法,所以新HashMap中最后的顺序是C,B,A,如上图所示。有了这些预知,我们来看看无限循环是怎么诞生的。
00-1010无限循环是由并发HashMap扩展引起的。在并发扩展的第一步,线程T1和T2需要扩展HashMap。此时,T1和T2指向链表的头节点元素A,而T1和T2的下一个节点,即T1.next和T2.next,指向节点B,
如下图所示:
00-1010无限循环的第二步是线程T2用完时间片并进入睡眠,而线程T1开始执行扩展操作。扩容之后的场景如下图所示:.直到线程T1的扩展完成,线程T2才被唤醒
从上图可以看出,线程T1执行后,HashMap的顺序因为head插入方法发生了变化,但是线程T2对发生的一切是不可知的,所以它的pointing元素保持不变。如上图所示,T2指向元素A,节点T2.next指向元素b
目录
当线程 T1 执行完,而线程 T2 恢复执行时,死循环就建立了,如下图所示:
因为T1扩展后节点B的下一个节点是A,而T2线程指向的第一个节点是A,第二个节点是B,这个顺序正好与T1扩展后节点的顺序相反。T1 执行完之后的顺序是 B 到 A,而 T2 的顺序是 A 到 B,这样 A 节点和 B 节点就形成死循环了,这就是散列表无止境的原因。
前置知识
HashMap 死循环的常用解决方案有以下 3 个:
请改用线程安全的容器ConcurrentHashMap(推荐使用这种方案)。请改用线程安全的容器哈希表(低性能,不推荐)。用synchronized或者Lock锁定HashMap,然后操作,相当于多线程排队执行(比较麻烦,不推荐)。
死循环执行步骤1
JDK 1.7中出现HashMap无限循环。形成死循环的原因是HashMap使用了JDK 1.7中的头插入方法,头插入方法的链表是多线程的,HashMap是扩展的。这些点共同构成了HashMap的无限循环,可以用线程安全容器ConcurrentHashMap来代替。
关于为什么Java中的HashMap会产生无限循环的文章到此为止。关于HashMap无限循环的更多信息,请搜索popular IT之前的文章或者继续浏览下面的相关文章。我希望你以后能更多地支持流行音乐!