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

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


void transfer(Entry[] newTable, boolean rehash) { int newCapacity = newTable.length;for (Entry<K,V> e : table) {while(null != e) {Entry<K,V> next = e.next;if (rehash) {e.hash = null == e.key ? 0 : hash(e.key);}int i = indexFor(e.hash, newCapacity);e.next = newTable[i];newTable[i] = e;e = next;}}
}

transfer方法中,会将扩容前的键值对取出并进行遍历,其中:

  • 变量e存放的当前键值对。
  • 变量next是e所指向的后续键值对链表。

如下图所示

根据每个键的hash值,计算出在扩容后的桶下标后,就将e对应的键值对插入,之后e便会指向next中链表的头节点。

假设已有的HashMap中的键值对是按上图所示,且两线程同时触发了该HashMap的扩容机制。

在线程1停留在上图的时刻时,transfer方法刚开始执行,
此时的变量e为:

next为:

若线程1在此时刻停止,且线程2没有停顿的完成了整个扩容操作,在扩容后的Table状态如下:

key为16的键值对由于扩容,被重新分配到其他桶内,而由于jdk7的特性,后插入桶内的键值对会位于链表头部,因此最终结果如上图。

而此时对于线程1来说:
e为:

next为:

这是因为,虽然两个变量指向的链表节点不变,但其后续指向却被线程2的扩容操作改变了。

接下来,线程1在此基础上,继续transfer操作:

e转移到空桶内

新的e变为

新的next变为


e转移到桶内

新的e

新的next


由于此时的 e所指向的链表节点,就是桶内的队尾节点 (1->null),在插入链表首部后,桶内的链表队列变为

此时next又变为

死链便产生了

(例子是黑马JUC网课里的)

[Java]JDK1.7中HashMap的并发死链相关推荐

  1. JDK1.7扩容时为什么会产生并发死链问题

    问题: 1.JDK1.7为啥为产生并发死链问题 并发,即多线程同时访问HashMap 需要知道的一些前提知识: 1. JDK1.7是采用有插法进行节点的添加的 2. HashMap的扩容长度为原来的一 ...

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

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

  3. JDK1.7和JDK1.8中HashMap是线程不安全的,并发容器ConcurrentHashMap模型

    一.HashMap是线程不安全的 前言 只要是对于集合有一定了解的一定都知道HashMap是线程不安全的,我们应该使用ConcurrentHashMap.但是为什么HashMap是线程不安全的呢,之前 ...

  4. 详述 JDK1.7 中 HashMap 会发生死链的原因

    文章目录 前置知识 死循环执行步骤1 死循环执行步骤2 死循环执行步骤3 解决方案 总结 前置知识 HashMap死循环是一个比较常见.比较经典的问题,在日常的面试中出现的频率比较高,所以接下来咱们通 ...

  5. 七、JDK1.7中HashMap扩容机制

    导读 前面文章一.深入理解-Java集合初篇 中我们对Java的集合体系进行一个简单的分析介绍,上两篇文章二.Jdk1.7和1.8中HashMap数据结构及源码分析 .三.JDK1.7和1.8Hash ...

  6. JDK1.7中HashMap底层实现原理

    JDK1.7中HashMap底层实现原理 一.数据结构 HashMap中的数据结构是数组+单链表的组合,以键值对(key-value)的形式存储元素的,通过put()和get()方法储存和获取对象. ...

  7. Day1、为什么JDK1.8中HashMap从头插入改成尾插入

    目录 Day1.为什么JDK1.8中HashMap从头插入改成尾插入 存储方式 静态常量 插入元素 扩容 拓展问题 1.为什么JDK1.8采用红黑树存储Hash冲突的元素? 2.为什么在长度小于8时使 ...

  8. 八、JDK1.8中HashMap扩容机制

    导读 前面文章一.深入理解-Java集合初篇 中我们对Java的集合体系进行一个简单的分析介绍,上两篇文章二.Jdk1.7和1.8中HashMap数据结构及源码分析 .三.JDK1.7和1.8Hash ...

  9. jdk1.8中HashMap扰动函数及数组长度为什么是2的n次方介绍

    文章目录 前言 一.什么是二进制? 二.计算机采用二进制的原因 三.十进制与二进制相互转换 十进制转成二进制 二进制转换为十进制 与.或.异或运算 按位异或 按位与运算 按位或运算 Jdk1.8中Ha ...

最新文章

  1. C++中 gets()函数
  2. python 一些方法的时间测试
  3. Property Animator 属性动画概述与示例
  4. linux基础应用和常用技巧
  5. kubernetes集群搭建
  6. 蓝桥杯 ADV-82 算法提高 填充蛋糕
  7. 谷歌收购DNNresearch能获得什么?
  8. 拥有mac动态壁纸Backgrounds——让桌面更生动
  9. 斯坦福机器学习教程学习笔记之1
  10. 计算机双人游戏玩不了,PC上的双人单机游戏
  11. c++ grpc 安装
  12. 一款好用的bi报表软件,让你站在Excel的肩膀上
  13. kali2022.1 firefox developer (换成开发者版本火狐)
  14. matlab用ode23解决参数方程,matlab变参量微分方程处理
  15. 3.3V过压保护电路
  16. Problem Driven Pattern, Coaching Pattern Series
  17. 嵌入式学习⑤——STM32嵌入式应用系统设计
  18. mes系统故障_MES系统目前存在哪些问题?
  19. 内最有份量的破解下载网站一览
  20. 8255A方式0应用

热门文章

  1. 【JavaWeb】Request对象详解
  2. oracle11g闪退 win7,win7 oracle11g
  3. java泡妞代码_java泡妞小程序
  4. bilibili视频爬取报错
  5. 4k电视接电脑鼠标延迟解决
  6. Cookie是什么及用法详解
  7. 教你一步解决大部分wallpaper engine使用时卡顿、鼠标延迟的问题
  8. VS 2013使用ReportViewer 提示An error occurred during local report processing异常处理
  9. 解决在vue中切换图片,gif格式的图片停在最后一帧的问题
  10. golang关于panic的解析