hashmap 死循环,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之前的文章或者继续浏览下面的相关文章。我希望你以后能更多地支持流行音乐!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: