jdk1.7下HashMap的头插法问题_乐乐Java路漫漫的博客-程序员宝宝_hashmap头插法问题

技术标签: java  hashmap  

jdk1.7,hashmap才用的是头插法,虽然hashmap并不是线程安全的容器,但是在并发情况下,使用hashmap会带来一个问题:

并发情况下,如果插入元素的两个线程都调用了rehash方法,即扩容方法,会导致链表成环的问题。

hashmap成环原因的代码出现在transfer代码中,也就是扩容之后的数据迁移部分(如下):

/**
     * Transfers all entries from current table to newTable.
     */
    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的过程:

首先获取新表的长度,之后遍历新表的每一个entry,然后每个ertry中的链表,以反转的形式,形成rehash之后的链表。

并发问题:

若当前线程此时获得ertry节点,但是被线程中断无法继续执行,此时线程二进入transfer函数,并把函数顺利执行,此时新表中的某个位置有了节点,之后线程一获得执行权继续执行,因为并发transfer,所以两者都是扩容的同一个链表,当线程一执行到e.next = new table[i] 的时候,由于线程二之前数据迁移的原因导致此时new table[i] 上就有ertry存在,所以线程一执行的时候,会将next节点,设置为自己,导致自己互相使用next引用对方,因此产生链表,导致死循环。

参考:https://www.cnblogs.com/chanshuyi/p/java_collection_hashmap_17_infinite_loop.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/b1303110335/article/details/111988764

智能推荐

彻底搞懂 c++ 函数参数的 & 和 &&_Hitaku的博客-程序员宝宝_函数 参数 &&

&amp;amp;amp;如果你在网上看到 c++ 的几种传参方式,肯定就分成两种,“值传递”和“引用传递”。值传递很简单,复制一份就是了;“引用传递”就说的马马虎虎了。“传递的是实参的本身”,说起来很轻松,实际上很有问题。最简单的一个问题就是:“实参”本身不是一个东西怎么办?例如:void f_ck(int &amp;amp;amp; i) { i++;}... fuck(1); // 编译不通过,...

phpstudy mysql创建表_MySQL_Mysql入门基础 数据库创建篇,1.创建数据表---基础(高手跳 - phpStudy..._weixin_39743511的博客-程序员宝宝

Mysql入门基础 数据库创建篇1.创建数据表---基础(高手跳过)正统方法:create [TEMPORARY] table 表名 [if not exists](创建的列项定义)[表的选项][分区的选项];#正统的创建方式,具体的参数,请参考mysql手册,在这里不做详细的解释,只说一些比较特别的。例:复制代码 代码如下:create table user(id int unsigned no...

我眼中的人工智能_启航奔向终点的博客-程序员宝宝_我眼中的人工智能

在计算机领域最吸引我的并非人工智能不可,上午看了看交大的一个教授对人工智能的讲解 发现它可以分为强人工智能跟弱人工智能 而现在的大部分智能产品归属于弱人工智能,虽然说这些产品在某一领域的技能远远超过人类,但其他领域可能就犹如刚出生的婴儿。还有就是大部分的产品都是以执行命令的方式运行的它们没有属于自己的意识思想 更别说是生命 就比如说 你拿着一张照片(照片内容假设是一个男生肩膀上扛着巨大的包..._1671465600

软件安装与仿真设置 -- 慕司板IAP15_weifengdq的博客-程序员宝宝

KeilKeil有多个版本,如用于51单片机的C51版本、用于ARM的MDK版本等,这里我们当然选择Keil C51。虽然最新的Keil C51已经到c51v953(Keil 5)了,但其应用并不大方便,所以,我们依然选择好用的c51v900版本来安装:在网盘搜索引擎:http://so.baiduyun.me/ 或微盘资源:http://vdisk.weibo.com/中搜索c51v900.exe

vb python混合编程_VB6+Python混合编程(COM组件)_weixin_39736606的博客-程序员宝宝

Python的方便不用说,VB6做GUI的简单程度更不用说。二者混合编程的需求一直非常旺盛,但我苦苦搜寻了很久,始终未找到合适的解决方案。在很长一段时间内,我都是通过创建、读取、删除临时文件来在VB程序和Python程序间传递信息,麻烦,且低级。(如下)比如下面是一个典型的处理流程 1. VB创建需要处理的文本please.txt,并调用Python 2. Python读取、处理文本,...

"undefined reference to" 问题解决方法_WQLYQY的博客-程序员宝宝_/usr/bin/ld: linux_test.cpp:(.text+0x75): undefine

最近在Linux下编程发现一个诡异的现象,就是在链接一个静态库的时候总是报错,类似下面这样的错误:(.text+0x13): undefined reference to `func'     关于undefined reference这样的问题,大家其实经常会遇到,在此,我以详细地示例给出常见错误的各种原因以及解决方法,希望对初学者有所帮助。1.  链接时缺失了相关目标文件(.o)

随便推点

新手linux安装vasp_史上最简单的VASP安装教程-非虚拟机_weixin_39746552的博客-程序员宝宝

本文是针对vasp初学者的安装教程编译器以及VASP都已编译号直接解压到系统中即可用,故不用配置其它的库文件以及环境;本教程适用于任意平台安装centos7的服务器以及pc机(若在其它linux发行版本中安装请咨询小编)。一、VASP安装需要的软件本教程相关使用软件下载链接:centos任意版本intel编译器以及License文件vasp安装包vasp测试算例二、安装过程1、使用ftp上传下载的..._1671465600

hdu4857(逃生)_ElephantFlySong的博客-程序员宝宝

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857逆序建图,编号大的往前排,倒序输出。为什么要这么做呢?首先这是要求编号小的尽量排在前面,而不是字典序最小。例如:13 13 1那么字典序最小的话就是 2 3 1,而 1 却应该在 2 的前面,这样正确答案就应该是3 1 2。怎么办呢?首先把图的有向边全部逆过来然后倒

Velodyne 32C Win端和Ubuntu18下使用_Y. F. Zhang的博客-程序员宝宝

Winhttps://blog.csdn.net/i_robots/article/details/109864454Ubuntu激光雷达用以太网连接电脑;设置ipv4:IP地址:192.168.1.x(x可以为1到254除开201以外的所有值,因为201是激光雷达的IP),我设的192.168.1.70子网掩码:255.255.255.0安装好ros melodic;新建ROS工程mkdir -p catkin_velodyne/srccd catkin_vel_1671465600

Websphere6.1的安装与配置_达摩院扫地僧的博客-程序员宝宝

websphere6.1.X安装与配置1、Red Hat Enterprise Linux AS release 4 上安装firefox2.0下载firefox-2.0.tar.gz,gz包解压:tar zxvf xx.tar.gz启动firefox若报错:找不到libstdc++.so.5,请安装compat-libstdc++-33-3.2.3-47.3.i386.rpm,安装r

iOS服务器证书不受信任的解决版本_diankuini1374的博客-程序员宝宝

参考文章链接:https://www.cnblogs.com/v-jing/p/6008964.htmlhttp://www.cocoachina.com/ios/20151021/13722.htmlhttps://www.cnblogs.com/weak/p/6142508.htmlhttp://blog.csdn.net/samuelandkevin/article...

linux设置权限掩码命令-----umask_虚伪的空想家的博客-程序员宝宝

umaskumask命令用来设置限制新建文件权限的掩码。当新文件被创建时,其最初的权限由文件创建掩码决定。用户每次注册进入系统时,umask命令都被执行, 并自动设置掩码mode来限制新文件的权限。用户可以通过再次执行umask命令来改变默认值,新的权限将会把旧的覆盖掉。语法umask 【选项】 【参数】选项-S:以文字的方式来表示权限掩码-p:输出的权限掩码可直接作为指令来执行...

推荐文章

热门文章

相关标签