问题:

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扩容时为什么会产生并发死链问题相关推荐

  1. [Java]JDK1.7中HashMap的并发死链

    [Java]JDK1.7中HashMap的并发死链 HashMap的并发死链现象发生在扩容时,在扩容过程中**transfer()**方法负责把旧的键值对转移到新的表中,其代码如下: void tra ...

  2. Java中的集合类——HashMap中的并发死链

    Java中的集合类--HashMap中的并发死链 ReHash过程 正常的ReHash过程: 并发的Rehash过程 解决办法 ReHash过程 正常的ReHash过程: 并发的Rehash过程 (1 ...

  3. 【死链】JDK1.7中HashMap在多线程环境的并发问题源码分析

    文章目录 一.HashMap在JDK1.7中的并发问题 二.死链如何产生? 三.如何解决HashMap并发问题 参考文献 一.HashMap在JDK1.7中的并发问题 在JDK1.7中的HashMap ...

  4. HashMap1.7 扩容时产生死链

    目录 HashMap1.7 扩容机制 扩容时产生死链 原因 产生过程 HashMap1.7 扩容机制 HashMap1.7 扩容机制:当 put 一个新键值对时:发生了哈希碰撞(hash值相同)并且加 ...

  5. HashMap扩容时的rehash方法中(e.hash oldCap) == 0算法推导

    PS:由于文档是我在本地编写好之后再复制过来的,有些文本格式没能完整的体现,故提供下述图片,供大家阅览,以便有更好的阅读体验: HashMap在扩容时,需要先创建一个新数组,然后再将旧数组中的数据转移 ...

  6. Java常见问题之HashMap扩容、树化、死链

    写在前边 HashMap属于比较常用的数据结构了,面试过程中也经常会被问到,本篇就知识点,展开问答式分析,重点聊聊hash冲突.扩容死链.容量为2的n次方.1.7和1.8之间的区别等问题~ 如何解决H ...

  7. JDK1.8之前造成HashMap死链问题

    针对阿里开发规范编程规约并发处理:HashMap 在容量不够进行 resize 时由于高并发可能出现死链,导致 CPU 飙升,在开发过程中可以使用其它数据结构或加锁来规避此风险. 分析造成原因: 当新 ...

  8. Java中HashMap常见问题 -- 扩容、树化、死链问题

    写在前边 HashMap属于比较常用的数据结构了,面试过程中也经常会被问到,本篇就知识点,展开问答式分析,重点聊聊hash冲突.扩容死链.容量为2的n次方等问题~ 1.7和1.8有什么不同 1.7是 ...

  9. 计算机考试是电脑卡住了怎么办,CPA机考时,电脑黑屏、死机了怎么办-之了课堂...

    距离2020年注册会计师考试还有10天左右的时间,大家都准备的怎么样呢?众所周知,注册会计师考试是机考,就是电脑作答,那么电脑作答最怕的就是突然死机或者黑屏,近期就有考生来咨询之了君:CPA机考时,电 ...

最新文章

  1. SAP删除会计科目 OBR2
  2. 数仓主题表怎么设计_陶瓷企业展厅设计主题风格怎么确定?
  3. 学习JavaScript需要什么基础?
  4. PyCharm使用期间出现报错集合 持续更新ing
  5. Linux下部署MongoDB
  6. 2017CCPC哈尔滨 F:Permutation(构造)
  7. [译]JS闭包:For循环中的setTimeout
  8. 011:求排列的逆序数
  9. JavaAPI之Runtime类以及bat文件开启应用程序
  10. 科睿唯安官网更新SCI期刊列表,慎投2月已被剔除期刊
  11. vmare下Linux空间扩大教程(chinaitlab)
  12. 科学计算机的删除键在哪里,电脑删除键是哪个?
  13. 把计算机怎么连接手机的网络助手在哪里,手机如何连接电脑上网
  14. 2023新疆大学计算机考研信息汇总
  15. 免费asp.net空间
  16. C 龟兔赛跑题目:T分钟后乌龟和兔子谁跑得快?
  17. 小米开发版安装magisk_MIUI10开发版/安卓P完美xposed与magisk框架教程
  18. F5 GTM DNS 知识点和实验 6 -智能DNS算法
  19. java读取图片文字
  20. PN532半加密、无漏洞卡解密

热门文章

  1. Android的DrawText详解
  2. 计算经纬度之间的距离
  3. Android 简述touch事件中的MotionEvent
  4. rewrite break
  5. BeautifulSoup使用
  6. go cobra初试
  7. centos 安装kermit
  8. Android开发中EventLog分析
  9. 服务器屏幕不全屏显示,服务器窗口显示不全屏
  10. 二叉树的前序、中序、后序