HashMap学习:1.7 迁移死循环分析(通俗易懂)

news2025/1/11 22:38:01

前言

JDK1.7由于采用的头插法,所以多线程情况下可能会产生死循环问题。

正文

头插法

在这里插入图片描述

就是每次从旧容器中的hash桶中取出数据后,放到新容器的头节点问题,如果此时头结点位置为空,直接放置即可,如果不为空将头节点的数据往后挪一位,让出位置给迁移节点。

容器迁移

void resize(int newCapacity) {
        Entry[] oldTable = table;
        int oldCapacity = oldTable.length;
        if (oldCapacity == MAXIMUM_CAPACITY) {
            threshold = Integer.MAX_VALUE;
            return;
        }
 
        Entry[] newTable = new Entry[newCapacity];
        transfer(newTable, initHashSeedAsNeeded(newCapacity));
        table = newTable;
        threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
    }

从以上代码可知,有两个线程的情况下会创建两个新的容器,当迁移完成后将新的容器覆盖到旧的上面;

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;
            }
        }
    }

迁移主要的思路是,遍历当前hash桶数组,从每个桶的头节点遍历,挨个迁移到新的组数的头节点,并且原来新节点的头节点往后移动;以上代码在多线程下可能产生死循环问题,下面分析下为什么会产生。

死循环分析

1、假设现在需要迁移的旧集合结构如下:

在这里插入图片描述

2、假设现在有两个线程1和线程2,由于他们都会创建新的容器,所以此时的结构如下:

在这里插入图片描述

3、假设线程2执行到此代码片段后被挂起了,恰好e=A,那next=B了,我们记住线程2的状态哈

在这里插入图片描述

4、线程1先获得CPU的执行权,当执行完成后的结构如下:

在这里插入图片描述

5、由步骤4可知,此时的A.next=null,B.next=A,此时的状态是正常的。线程2开始获取CPU的执行时间,由于每个线程都创建了一个新的容器,它此时的状态为步骤2中图片所示,线程2开始工作后,从步骤3中的代码段开始执行,由于代码段中保存了e=Anext=B,所以会先进行A的迁移,A迁移完成后由于代码中保存了next,所以还会对B进行迁移。

在这里插入图片描述

6、步骤5中还未形成死循环,由于线程1中迁移完成造成,B.next=A,所以代码块会判断B.next是否为null,不为null则拿出下个值进行迁移,由于next=A,所以又将A迁移到新的容量中去了。此时A.next=B,此时就真正形成了闭环。又对A进行判断是否有next…不断添加

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/659800.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言strncpy的使用缺陷和实现,strncat的使用缺陷和实现,strncmp的使用和实现。

1.strncpy 函数原型&#xff1a; char *strncpy( char *strDest, const char *strSource, size_t count );char *strDest 目标字符串首元素地址const char *strSource 源字符串(需要拷贝过去的字符串)size_t count 拷贝字符的个数char *strncpy 拷贝结束后&#xff0c;返回目…

Micormeter实战

Micrometer 为基于 JVM 的应用程序的性能监测数据收集提供了一个通用的 API&#xff0c;支持多种度量指标类型&#xff0c;这些指标可以用于观察、警报以及对应用程序当前状态做出响应。 前言 可接入监控系统 监控系统的三个重要特征&#xff1a; 维度&#xff08;Dimensio…

[保姆教程] Windows平台OpenCV以及它的Golang实现gocv安装与测试(亲测通过)

一、MinGW & CMake 预备步骤 首先打开cmd: c: md mingw-w64 md cmake下载安装MinGW-W64 访问&#xff1a; https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/7.3.0/ 下载&#xff1a; MinGW-W64 GCC-8…

一文详解Softmax的性质与Self-Attention初步解析

概述 最近研究超平面排列(Hyperplane Arrangement)问题的时候&#xff0c;发现ReLU有其缺陷&#xff0c;即举例来说&#xff0c;ReLU 无法使用单一的超平面将分离的所有数据&#xff0c;完整的输出&#xff0c;即只会输出半个空间映射的数据&#xff0c;而另一半空间的数据被置…

面试---简历

项目 1.1、商品管理 新增商品 同时插入商品对应的使用时间数据&#xff0c;需要操作两张表&#xff1a;product&#xff0c;product_usetime。在productService接口中定义save方法&#xff0c;该方法接受一张Dto对象&#xff0c;dto对象继承自product类&#xff0c;并将prod…

学习open62541 --- [78] 单线程和多线程的使用场景

open62541提供多线程功能&#xff0c;默认不开启&#xff0c;即单线程&#xff0c; 把UA_MULTITHREADING的值设置为 > 100就可以开启多线程了。 这里单线程/多线程的意思是基于open62541运行的server内部是否使用锁去保护数据。只要server运行后还有读写操作需要做&#x…

从源码全面解析 dubbo 消费端服务调用的来龙去脉

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小黄&#xff0c;独角兽企业的Java开发工程师&#xff0c;CSDN博客专家&#xff0c;阿里云专家博主&#x1f4d5;系列专栏&#xff1a;Java设计模式、Spring源码系列、Netty源码系列、Kafka源码系列、JUC源码…

3D 顶点着色与Phong 反射模型

Phong 反射模型有时被称为“Phong 照明”或“Phong 照明”。它由环境光照、漫反射&#xff08;朗伯反射&#xff09;、镜面反射三部分组成。 Phong 反射模型提供了一个方程式&#xff0c;用于计算表面上每个点的光照&#xff0c;I_p&#xff1a; 第一部分代表环境光项。在GLSL代…

X书hmac参数

被删重新发送 全文可以查看&#xff1a; 上面一遍unidbg解密shield文章 unidbg - 》 callObjectMethodV方法填写你的小红书路径下s.xml里的值: 或者在抓包响应头中: 查找xy-ter-str hmac 结果都是在&#xff0c;响应头里&#xff0c;所以 hmac 是服务器下发给客户端的. Over…

黑马头条.

文章目录 前言一、项目概述1.1 能收获什么1.2 项目概述1.3 项目术语1.4 业务说明 二、技术栈2.1技术栈整体框架图2.2技术栈简介 三、nacos环境搭建3.1 虚拟机镜像准备3.2 nacos的安装 四、初始工程搭建4.1 开发环境准备 五、实现登录功能5.1 需求分析5.2 表结构分析5.3 思路分析…

22道常见RocketMQ面试题以及答案

面试宝典到手&#xff0c;搞定面试&#xff0c;不再是难题&#xff0c;系列文章传送地址&#xff0c;请点击本链接。 1、RocketMQ是什么? 2、RocketMQ有什么作用&#xff1f; 3、RoctetMQ的架构 4、RoctetMQ的优缺点 8、消息过滤,如何实现&#xff1f; 9、消息去重,如果…

Elasticsearch 基本使用(四)聚合查询

聚合查询 概述单字段聚合查询统计分组后的数量非文档字段分组文档字段分组 其他聚合运算统计平均值统计总金额统计最大值自定义聚合结果排序简单聚合小结 多字段聚合查询 概述 说到聚合查询&#xff0c;马上会想到 SQL 中的 group by&#xff0c;ES中也有类似的功能&#xff0…

编程语言发展历史

文章目录 语言的发展时间轴语言世代时间轴1940年前-机器语言时代1940年后-汇编语言时代1950年-高级语言的初生1960年-高级语言的进一步成熟1980年-各大语言的进一步增强1990年代-飞速发展时代2000年-新时代 高级编程语言的分类解释型与编译型面向过程与面向对象 对语言的评价Ti…

【学习学习】NLP理解层次模型

NLP&#xff08;Neuro-Linguistic Programming&#xff0c;神经语言程序学&#xff09;&#xff0c;由两位美国人理查得.班德勒&#xff08;Richard Bandler&#xff09;与约翰.葛瑞德&#xff08;John Grinder&#xff09;于1976年创办&#xff0c;并在企业培训中广泛使用。美…

PyTorch 深度学习 || 4. 自编码网络 | Ch4.3 卷积自编码网络图像去噪

卷积自编码网络图像去噪 1. 数据的准备 先简单介绍一下训练网络使用到的图像数据集——STL10&#xff0c;该数据集可以通过torchvision.datasets模块中的STL10()函数进行下载&#xff0c;该数据集共包含三种类型数据,分别是带有标签的训练集和验证集&#xff0c;分别包含5000…

Cookie增删改查方法封装(低内存开销版)

本文章中的低内存开销是指在获取cookie的时候不进行字符串—>数组的转变&#xff0c;全程使用sliceindexOf切割字符串&#xff0c;不创建和操作数组&#xff0c;节约内存&#xff0c;本文代码已存放到github中&#xff0c;后续会持续完善功能&#xff0c;传送门&#xff1a;…

二进制方式部署kubernetes集群

二进制方式部署kubernetes集群 1、部署k8s常见的几种方式 1.1 kubeadm Kubeadm 是一个 k8s 部署工具&#xff0c;提供 kubeadm init 和 kubeadm join&#xff0c;用于快速部署 Kubernetes 集群。 Kubeadm 降低部署门槛&#xff0c;但屏蔽了很多细节&#xff0c;遇到问题很难…

掌握Python的X篇_4_开发工具ipython与vscode的安装使用

本篇将会介绍两个工具的安装及使用来提高Python的编程效率。 ipython&#xff1a;比python更好用的交互式开发环境vscode&#xff1a;本身是文本编辑器&#xff0c;通过安装相关的插件vscode可以作为python集中开发环境使用 掌握Python的X篇_4_开发工具ipython与vscode的安装使…

第四章 linux编辑器——vim的使用

第四章 linux编辑器——vim的使用 一、什么是vim&#xff1f;二、vim的基本操作1、模式之间的相互切换2、vim的常见命令集&#xff08;1&#xff09;正常模式的常见命令a. 模式切换b. 光标移动c.删除文字d.复制e.替换f.撤销g.更改 &#xff08;2&#xff09;底行模式的常见命令…

复习之linux的网络配置

一、基本定义 1.IP IP指网际互连协议&#xff0c;Internet Protocol的缩写&#xff0c;是TCP/IP体系中的网络层协议。 电脑之间要实现网络通信&#xff0c;就必须要有一个合法的ip地址。 IP地址网络地址主机地址&#xff08;又称&#xff1a;主机号和网络号组成&#xff09…