HashMap多线程下发生死循环的原因

HashMap多线程下发生死循环的原因

大家好,又见面了,我是全栈君。

概述


大神陈皓已经在疫苗:JAVA HASHMAP的死循环一文中详细描述了HashMap多线程下产生死循环的原因,我仔细研读了这篇大作,做了一些笔记,加上自己的一些理解
整理出一些信息,发出来与大家交流交流。


HashMap存储的数据结构


陈皓在Hash表数据结构这一节提到了HashMap的数据结构以及扩容问题,关于这一点我之前写过的
HashMap的put和get方法原理HashMap扩容已经有详细的描述了。


多线程rehash的时候如何造成闭环链表


rehash源代码

这里写图片描述

这里写图片描述

正常的rehash过程


数据准备
在size=2的HashMap中按照顺序添加5, 7, 3这三个key,假设按照mod 2的算法来计算元素数组下标,那么key 5,7,3都会落在下标为1的数组桶中(发生hash冲突),如下图:

这里写图片描述

把HashMap的size扩容为4后,rehash的过程

注意,发生hash冲突的5,7,3虽然都是在同一个链表中,但是每个元素都得走rehash的过程,因为HashMap扩容后,这几个元素就未必都是在同一个链表中了

1、第一个是处理3这个key,先把key为3这个元素的next设置为空,并计算它在新数组中的下标,并存到新下标对应桶中,如下图:

这里写图片描述

2、第二个是处理7这个key,按照上面的约定,在新数组中3和7这个两个key还是发生了hash冲突,那么按照HashMap发生冲突的处理代码,链表的第一个元素存储的是最新插入的7,然后next指向3,如下图:

这里写图片描述

3、第三个是处理5这个key,如下图:

这里写图片描述

到这里一次正常rehash过程走完了,最后三个key的存储情况如下图:

这里写图片描述

并发下的rehash过程


当两个并发线程thread1和thread2都同时进入到transfer时,也即是,刚好thread1和thread2都要对HashMap进行扩容,万一这个时候thread1执行下面的代码时,被线程调度器挂起了,而thread2则正常的把扩容的操作做完,如下图:

这里写图片描述

那这个时候,容器的数据存储情况如下:

对于thread1

这里写图片描述

对于thread2

这里写图片描述

这个时候,thread1拥有执行权限了,则继续它的扩容操作,等thread1扩容完后就产生了一个环形链表了(注意这里省略了一些步骤,不太明白的,则可以看我之前写的HashMap的put和get方法原理HashMap扩容)

这里写图片描述

这个时候,如果有个get请求,就有可能发生死循环,一直在链表中绕来绕去的,没法终止。


原文链接


HashMap多线程下发生死循环的原因

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108167.html原文链接:https://javaforall.net

(0)
上一篇 2022年3月6日 下午10:00
下一篇 2022年3月6日 下午11:00


相关推荐

  • 史上最牛的Linux视频教程—兄弟连 学习笔记1

    史上最牛的Linux视频教程—兄弟连 学习笔记17月24日3.1给初学者的建议——注意事项1.Linux严格区分大小写2.硬盘文件是/dev/sd[a-p]  光盘文件/dev/sr0等3.Linux没有扩展名4.Linux所有存储设备都必须挂载之后才能用(手工分配) 3.2给初学者的建议——服务器管理和维护1.sbin文件只有root才能用  boot目录保存内核和系统文件  dev保存设备硬…

    2022年5月24日
    40
  • Python编写网络爬虫–牛刀小试

    Python编写网络爬虫–牛刀小试本文参考网上的资料,编写简单的Python编写网络爬虫,做了网页内容的抓取,分析出链接的url并抓取。

    2022年6月17日
    32
  • 基于BGP协议的广域网流量调度SDN控制器在银行业的部署实践「建议收藏」

    基于BGP协议的广域网流量调度SDN控制器在银行业的部署实践「建议收藏」作者:王逊摘要:SDN作为网络自动化(NetworkAutomation)一种应用场景,从2009年Openflow的提出后在近几年已经进入到快速发展、现网部署阶段。SD-WAN实际上就是将SDN和网络自动化的思想和技…

    2025年9月24日
    5
  • django 自定义过滤器_adguard自定义过滤器

    django 自定义过滤器_adguard自定义过滤器前言虽然DTL给我们内置了许多好用的过滤器。但是有些时候还是不能满足我们的需求。因此Django给我们提供了一个接口,可以让我们自定义过滤器,实现自己的需求。自定义过滤器首先在某个app中,创建

    2022年7月31日
    7
  • Java 泛型擦除_java中泛型的使用

    Java 泛型擦除_java中泛型的使用java泛型的残酷现实就是:在泛型代码内部,无法获得任何有关泛型参数类型的信息。在使用泛型时,任何具体的类型都被擦除,唯一知道的是你在使用一个对象。比如:List<String>和List<Integer>在运行事实上是相同的类型。他们都被擦除成他们的原生类型,即List。snippet1:1packagecom.cognizant.ch15…

    2026年4月13日
    3
  • matlab fmincon优化,matlab fmincon优化问题[通俗易懂]

    matlab fmincon优化,matlab fmincon优化问题[通俗易懂]程序出现如下问题,—options.MaxFunEvals=400(thedefaultvalue).论文时间紧张,有时间的同学可以看一下吗?谢谢x0=[100;100;100;100];A=[];b=[];Aeq=[1,1,1,1];beq=[2000];VLB=[300;400;0;0];VUB=[600;1000;500;500];[x,fval]…

    2022年6月9日
    29

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号