JDK1.7扩容时为什么会产生并发死链问题
问题:
1、JDK1.7为啥为产生并发死链问题
- 并发,即多线程同时访问HashMap
需要知道的一些前提知识:
1、 JDK1.7是采用有插法进行节点的添加的
2、 HashMap的扩容长度为原来的一倍
JDK1.7单线程下的扩容:
1、进行节点的转移前,需要把数组长度变为原来的一倍
2、节点(Entry)转移的源代码
void transfer(Entry[] newTable, boolean rehash) {int newCapacity = newTable.length; //得到新数组的长度 for (Entry<K,V> e : table) { //第一步:遍历整个数组对应下标下的链表,e代表一个节点while(null != e) { //当e==null时,则该链表遍历完了,继续遍历下一数组下标的链表 Entry<K,V> next = e.next; //第二步:先把e节点的下一节点存起来if (rehash) { //得到新的hash值e.hash = null == e.key ? 0 : hash(e.key); }int i = indexFor(e.hash, newCapacity); //在新数组下得到新的数组下标e.next = newTable[i]; //第三步:将e的next指针指向新数组下标的位置newTable[i] = e; //第四步:将该数组下标的节点变为e节点e = next; //第五步:遍历链表的下一节点}}}
3、开始演示
- 看我贴出来的源码把重要的步骤分为五步
- 1、假设已经遍历到我们3这个节点对应下标的链表了。那么此时第一步的e节点,和第二步的next节点分别指向如下图所示的节点。
- 2、执行第三步:将e的next指针指向新数组下标的位置,如图所示:
- 3、执行第四步:将该数组下标的节点变为e节点,如图所示:
- 4、执行第五步:遍历链表的下一节点,如图所示:
- 5、此时一次while循环已经完毕,进入下次循环,执行第一步和第二步,执行后如图所示:
- 6、按照以上步骤,我们可以将节点2和节点1都移到新的数组中,全部移到新数组后如图所示:
4、总结
- JDK1.7的转移后元素的位置将反了。
JDK1.7多线程下的扩容:
1、我这里假设有两个线程分别为t1和t2,而且两个线程同时读到了需要扩容,这时候,就会导致会创建两个新的数组,而且同时要去操作这个老的数组的节点1,2,3,假设这时候两个线程都执行了第一步和第二步,这时候的状态如图所示:
2、假设这时候操作系统的时间片没有分到t2线程,只有t1线程在运行,那么按照单线程情况下转移的过程得到t1线程完成转移后如图所示:
3、接下来是t2线程运行了,那么此时移动的便是t1线程新创建的表中的节点1,2,3;现在来详细说明一下这些步骤;
1)上面讲了,t2线程已经完成了源码内容的第一步和第二步的操作,接下来进行第三步:将e2的next2指针指向t2线程创建的新数组下标的位置,如图所示:
2)接下来执行第四步操作:将该数组下标的节点变为e2节点,如图所示:
接下来执行第五步操作:遍历链表的下一节点,如图所示:
进入新循环,再执行第一步和第二步的操作,执行后结果如图所示:
接下来执行第三步操作,结果如图所示:
接下来执行第四步操作,结果如图所示:
接下来执行第五步操作遍历下一节点(重点来了),如图所示:
再次进入下一次循环,执行第一步和第二步的操作,如图所示:
接下来执行第三步操作,如图所示:
接下来执行第四步操作,如图所示:
接下来也不用演示了,节点2和节点3会一直循环下去,可以导致程序一直执行,问题就很严重了,电脑直接卡死,可能还会抛出OutOfMemoryException;而且你们有没有发现,节点1给丢弃了,导致丢值的现象。
4、扩展:
虽然JDK1.8的HashMap采用尾插法避免了上述的问题,但仍旧是线程不安全的;所以如果要使用线程安全的HashMap,建议使用ConcurrentHashMap。
5、留言:
- 有不对的地方还望大家积极留言纠错。
JDK1.7扩容时为什么会产生并发死链问题相关推荐
- [Java]JDK1.7中HashMap的并发死链
[Java]JDK1.7中HashMap的并发死链 HashMap的并发死链现象发生在扩容时,在扩容过程中**transfer()**方法负责把旧的键值对转移到新的表中,其代码如下: void tra ...
- Java中的集合类——HashMap中的并发死链
Java中的集合类--HashMap中的并发死链 ReHash过程 正常的ReHash过程: 并发的Rehash过程 解决办法 ReHash过程 正常的ReHash过程: 并发的Rehash过程 (1 ...
- 【死链】JDK1.7中HashMap在多线程环境的并发问题源码分析
文章目录 一.HashMap在JDK1.7中的并发问题 二.死链如何产生? 三.如何解决HashMap并发问题 参考文献 一.HashMap在JDK1.7中的并发问题 在JDK1.7中的HashMap ...
- HashMap1.7 扩容时产生死链
目录 HashMap1.7 扩容机制 扩容时产生死链 原因 产生过程 HashMap1.7 扩容机制 HashMap1.7 扩容机制:当 put 一个新键值对时:发生了哈希碰撞(hash值相同)并且加 ...
- HashMap扩容时的rehash方法中(e.hash oldCap) == 0算法推导
PS:由于文档是我在本地编写好之后再复制过来的,有些文本格式没能完整的体现,故提供下述图片,供大家阅览,以便有更好的阅读体验: HashMap在扩容时,需要先创建一个新数组,然后再将旧数组中的数据转移 ...
- Java常见问题之HashMap扩容、树化、死链
写在前边 HashMap属于比较常用的数据结构了,面试过程中也经常会被问到,本篇就知识点,展开问答式分析,重点聊聊hash冲突.扩容死链.容量为2的n次方.1.7和1.8之间的区别等问题~ 如何解决H ...
- JDK1.8之前造成HashMap死链问题
针对阿里开发规范编程规约并发处理:HashMap 在容量不够进行 resize 时由于高并发可能出现死链,导致 CPU 飙升,在开发过程中可以使用其它数据结构或加锁来规避此风险. 分析造成原因: 当新 ...
- Java中HashMap常见问题 -- 扩容、树化、死链问题
写在前边 HashMap属于比较常用的数据结构了,面试过程中也经常会被问到,本篇就知识点,展开问答式分析,重点聊聊hash冲突.扩容死链.容量为2的n次方等问题~ 1.7和1.8有什么不同 1.7是 ...
- 计算机考试是电脑卡住了怎么办,CPA机考时,电脑黑屏、死机了怎么办-之了课堂...
距离2020年注册会计师考试还有10天左右的时间,大家都准备的怎么样呢?众所周知,注册会计师考试是机考,就是电脑作答,那么电脑作答最怕的就是突然死机或者黑屏,近期就有考生来咨询之了君:CPA机考时,电 ...
最新文章
- SAP删除会计科目 OBR2
- 数仓主题表怎么设计_陶瓷企业展厅设计主题风格怎么确定?
- 学习JavaScript需要什么基础?
- PyCharm使用期间出现报错集合 持续更新ing
- Linux下部署MongoDB
- 2017CCPC哈尔滨 F:Permutation(构造)
- [译]JS闭包:For循环中的setTimeout
- 011:求排列的逆序数
- JavaAPI之Runtime类以及bat文件开启应用程序
- 科睿唯安官网更新SCI期刊列表,慎投2月已被剔除期刊
- vmare下Linux空间扩大教程(chinaitlab)
- 科学计算机的删除键在哪里,电脑删除键是哪个?
- 把计算机怎么连接手机的网络助手在哪里,手机如何连接电脑上网
- 2023新疆大学计算机考研信息汇总
- 免费asp.net空间
- C 龟兔赛跑题目:T分钟后乌龟和兔子谁跑得快?
- 小米开发版安装magisk_MIUI10开发版/安卓P完美xposed与magisk框架教程
- F5 GTM DNS 知识点和实验 6 -智能DNS算法
- java读取图片文字
- PN532半加密、无漏洞卡解密