首页 > 其他分享 >hashmapjdk1.7死循环问题

hashmapjdk1.7死循环问题

时间:2023-09-11 20:56:40浏览次数:39  
标签:hashmapjdk1.7 链表 hash arrayNew next 问题 插入 线程 死循环

hashmap是在jdk1.7是数组+链表,通过hash计算出数组下标位置以后,如果同一个位置有多个元素,放在链表中,在多线程插入,并同时扩容的并发环境会出现死循环问题

头插入法

在维护链表元素的过程中,有一个head指针,指向第一个元素,没有尾部指针(未插入需要维护一个尾部指针,才能快递定位在哪里插入)。

举例子:A->B->C 这样一个结构使用头插入一个新元素D以后D->A->B->C

如果正好要扩容,那么久先扩容然后再插入,扩容也是头插入发

扩容以后变成
A->B->C 变成 C->B->A ,然后再插入 D ,D->C->B->A

单线程情况扩容过程

arrayOld ,arrayNew 两个集合,外层循环遍历数组,内层遍历链表

A->B->C

内循环过程

初始e = A;

next = e.next;备注B

e.next = arrayNew[hash];把A的next指向性的集合,第一次是null。

arrayNew [hash] = e;新集合的第一个元素指定为A

e=next;next是B然后开始第二次内循环

...

直到 C.next 是 null 退出循环,结果就是顺序倒过来

死循环产物过程

两个线程要插入元素,hash值相等,同一个下标,达到扩容条件,先触发扩容,然后触发插入,实际上插入我们都不关心了,扩容的过程多线程就有可能出现死循环。

假设还是 A->B->C

线程1,扩容进行到一半并且保存部分变量

​ 初始e = A;

​ next = e.next;备注B

​ 线程暂停......然后线程2执行玩扩容以后它才会继续,这时候 e=A,next=B 是放在本地方法栈中,我们先去看线程2

​ e.next = arrayNew[hash];把A的next指向性的集合,第一次是null。

​ arrayNew [hash] = e;新集合的第一个元素指定为A

​ e=B

​ 这时候新集合是 A

第二轮循环

e=B;

next=e.next;线程2已经 把原链表改成C->B->A了,所以这时候是A,如果不出线程安全问题,它应该是C

e.next = arrayNew[hash];这时候新集合链表已经是B->A了

arrayNew [hash] = e;新集合的第一个元素指定为B
e=next,next这时候是A,不是C

第三轮循环

e=A;

next=A.next;是null;

e.next= arrayNew[hash];第二次循环的结果就是新集合链表已经是B->A了然后 a.next指向 B->的链表 ,结果就是A<->B,已经出问题了。

arrayNew [hash] = e;这时候把头节点指向A 这时候新集合的这个下标的链表 头节点指向A ,然后AB成环。

e=next;null退出循环。

线程2,直接扩容完成,容量倍增是原数据的2倍,但是当前生效的是和线程1 共用的。

​ 线程2 执行完成以后数组里面的链表结果C->B->A

结论:hashmap本来就非线程安全的,在多线程环境本来就不应该用它,即便不出死循环问题,也会出别的问题。这并不是一个bug,而是hashmap本来就没有支持多线程环境。新版本使用为插入不会改变顺序不会出现死循环,但是多线程插入还是会数据不一致。

标签:hashmapjdk1.7,链表,hash,arrayNew,next,问题,插入,线程,死循环
From: https://www.cnblogs.com/cxygg/p/17694472.html

相关文章

  • 排列中的数值问题(改编自NOIP2018程序填空第2大题)
    题目描述对于一个\(1\)到\(n\)的排列\(p_1,p_2,\ldots,p_n\)(即\(1\)到\(n\)中每一个数在数列\(p\)中出现了恰好一次),令\(q_i\)为第\(i\)个位置之后第一个比\(p_i\)值更大的位置,如果不存在这样的位置,则\(q_i=n+1\)。举例来说,如果\(n=5\)且\(p\)为......
  • 关于sql server 2008 r2 安装闪退问题解决办法
    打开sqlserverr2安装包文件目录找到SQL2008R2_64\2052_chs_lp\x64\setup\sqlsupport_msi目录下sqlsupport.msi,运行安装 a、在安装盘中搜索sqlsupport,找到对应的sqlsupport.msi文件并安装,一般路径如下:Windows64位系统需要安装:..\sql2008r2.iso\2052_chs_lp\x64\setup\sqls......
  • Bypass:URL非法参数名产生的绕过问题
    测试测试demo:<?phphighlight_file(__FILE__);error_reporting(0);$var=$_REQUEST["mochu."];var_dump($_REQUEST);echo"PHP-Version:".phpversion()."<br>";if(is_null($var)){die("<br>$varisnull")......
  • 括号匹配问题
    1.题目设表达式中包含三种括号:圆括号、方括号和花括号,它们可互相嵌套,如({})或({([][()])})等均为正确的格式,而{[])}、{()]或([]}均为不正确的格式。2.算法分析3.////Createdbytrmbhon2023-09-11.//#include<stdio.h>#include<stdlib.h>#include<string.h>#define......
  • 33socket套接字/黏包问题
    socket套接字#需求:编写一个cs架构的程序实现数据交互思考:需要编写代码操作OSI七层相当的复杂由于操作OSI七层是所有cs架构的程序都需要经历的过程所以有固定的模块socket套接字是一门技术socket模块>>>:提供了快捷方式不需要自己处理每一层"""以后我们写......
  • pycharm 远程debug卡住问题解决
     解决方案:1、先注释掉连接debugserversocket代码,启动 2、启动debugserver3、去除注释,热部署自动重启,则能重连 ......
  • 亚马逊云科技与德勤中国推出新工具,有效缓解生成式AI时代下的安全问题
    随着人工智能技术的飞速发展,生成式AI应用越发广泛,在各领域迎来了新的机遇,但同时也在安全层面给企业带来了新的挑战。网络、数据泄露、隐私侵犯等安全威胁,以及法律法规的不断更新,使跨区域运营过程中的网络安全和合规成为企业持续发展不可或缺的一环。 亚马逊云科技与全球核心级咨询......
  • MAVEN中的问题
    MAVEN中的问题1.版本问题Maven3.6.2。解决方法:降低到3.6.1 2.Tomcat闪退3.IDEA中每次都要重复配置Maven在IDEA中的全局默认配置中去配置  4.Maven项目中Tomcat无法配置5.maven默认web项目中的web.xml版本问题 6.替换为webapp4.0版本和tomcat<?xmlversion......
  • 解决Python中的包管理与依赖问题代码实操
    Python的包管理与依赖问题是一个常见的挑战,但通过以下具体的解决方案和步骤,你可以更好地处理和管理项目中的依赖关系,提高开发效率。1.使用虚拟环境进行包管理步骤:a.安装虚拟环境工具,比如venv或者virtualenv。在命令行中输入以下命令安装venv:```$python3-mvenvmyenv```b.创建虚......
  • 【JAVA日常】关于jeecgBoot @Dict注解的使用不生效问题
    项目中后端使用jeecgBoot开发,最近正好遇到一些关于改造和使用@dict字典注解的问题,正好记录一下,以防忘记。1、注解不生效问题1今天公司同事问,说这个注解加上了怎么还不起作用呢。我们就检查了代码中的使用。注解的添加以及使用都正常,然后排查发现接口调用时未执行字典的切面,那么......