iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >HashMap在高并发下会出现什么问题
  • 408
分享到

HashMap在高并发下会出现什么问题

2023-06-20 19:06:12 408人浏览 泡泡鱼
摘要

本篇内容介绍了“HashMap在高并发下会出现什么问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言众所周知,HashMap不是线程安全

本篇内容介绍了“HashMap高并发下会出现什么问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

前言

众所周知,HashMap不是线程安全的,在高并发情况下会出现问题。特别是,在java1.7中,多线程的HashMap会出现CPU 100%的严重问题。这个问题是怎样产生的,后续版本还会有这个问题吗(指java8及后续版本)?下面就来用通俗的语言讲解下。

解析

关于这个问题,是由于java7多线程扩容机制下链表变为循环链表,再获取该链表导致的。

看下java7中扩容的代码。java7中HashMap的实现为数组+链表的形式,没有红黑树。

java7扩容的原则很简单,新数组长度为原数组2倍。遍历原数组,将数组每个位置(有可能为空,有可能只有一个数组,有可能是一个链表)重新哈希,放到对应的新数组上。全部遍历完后更改数组指针,指向新数组。需要注意的是,这里重哈希将链表元素放到新数组,使用的是头插法。

 // 扩容核心方法,基本思想就是遍历数据,使用头插法将旧数组元素移到新数组。 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]; // 头插法,新节点next指向该位置首节点                newTable[i] = e; // 新元素归位                e = next; // 指向下一个节点,继续遍历            }        }    }   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);    }

这里处理的话,如果单线程情况下不会有问题。如果在多线程情况下,会导致链表在扩容过程中形成循环链表。

形成循环链表的原因在于多线程和头插法。试想,两个线程在添加元素时,同时发现该扩容了,然后同时发起扩容过程。由上述代码可知,扩容完成之前是在自己的线程里创建一个新数组。等扩容完成后(也就是将原数组元素迁移到新数组后)再更改指针指向新扩容数组。

举例初始HashMap是这样的

HashMap在高并发下会出现什么问题

假设两个线程同时扩容,一个线程扩容到一半后被挂起。(标识了某链表的e和next),另一个线程执行扩容,且完成了扩容。

HashMap在高并发下会出现什么问题

红色的数组和元素表示线程1,也就是扩容一半挂起的线程,而线程二已完成扩容。观察完成扩容的线程二,在3的位置,该链表的位置顺序已经改变(原数组顺讯为3->7,现在反过来了,这是使用头插法的效果,你也可以对着代码试试)。从图中也可以看出,线程1,2分别创建了自己的新数组,并在自己的新数组中完成扩容。

这时线程1开始执行。熟悉下它即将执行的代码。

   // transfer 方法循环部分         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]; // 头插法,新节点next指向该位置首节点                newTable[i] = e; // 新元素归位                e = next; // 指向下一个节点,继续遍历            }

下面线程1将使用头插法将元素插入线程1新建的数组中去。注意此时e指向的是Key3,next指向的是Key7。不用想也知道后面操作会有问题。因为现在的next指针指的不是e的下一个元素,而是它的前一个元素!

如果继续走代码的话,把Key3(当前e指向元素)放入新数组后,再把Key7放入新数组,后面会放哪个元素?当然又是Key3了,因为Key7next是Key3,这样就形成了死循环。

HashMap在高并发下会出现什么问题

java8的改进

  • 添加了红黑树,当链表长度大于8时,会将链表转为红黑树。

  • 扩容后,新数组中的链表顺序依然与旧数组中的链表顺序保持一致。具体jdk8是用 head 和 tail 来保证链表的顺序和之前一样,这样就不会产生循环引用。也就没有死循环了。

  • 虽然修复了死循环的BUG,但是HashMap 还是非线程安全类,仍然会产生数据丢失等问题。

“HashMap在高并发下会出现什么问题”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: HashMap在高并发下会出现什么问题

本文链接: https://www.lsjlt.com/news/299281.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • HashMap在高并发下会出现什么问题
    本篇内容介绍了“HashMap在高并发下会出现什么问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言众所周知,HashMap不是线程安全...
    99+
    2023-06-20
  • 浅谈HashMap在高并发下的问题
    前言 总所周知,HashMap不是线程安全的,在高并发情况下会出现问题。特别是,在java1.7中,多线程的HashMap会出现CPU 100%的严重问题。这个问题是怎样产生的,后续...
    99+
    2024-04-02
  • Redis在高并发情况下可能会存在哪些问题
    本篇文章为大家展示了Redis在高并发情况下可能会存在哪些问题,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1、缓存穿透:当用户请求参数为param=zsan 的时...
    99+
    2024-04-02
  • Macosx下使用docker/mysql会出现什么问题
    这篇文章主要为大家展示了“Macosx下使用docker/mysql会出现什么问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Macosx下使用docker/...
    99+
    2024-04-02
  • 如何解决HashMap并发时会引起死循环的问题
    这篇文章给大家分享的是有关如何解决HashMap并发时会引起死循环的问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。今天研读Java并发容器和框架时,看到为什么要使用ConcurrentHashMap时,其中有...
    99+
    2023-06-15
  • 关于HashMap 并发时会引起死循环的问题解析
    今天研读Java并发容器和框架时,看到为什么要使用ConcurrentHashMap时,其中有一个原因是:线程不安全的HashMap, HashMap在并发执行put操作时会引起死循...
    99+
    2024-04-02
  • ddos网站会出现什么问题
    ddos网站会出现的问题有:会使服务器CPU被大量占用,从而导致网站出现打开缓慢的情况。占用带宽资源是ddos攻击的一个主要手段,网络带宽被大量无效数据给占据时,正常流量数据请求很难被服务器进行处理。网站服务器被大量ddos攻击时,会出现死...
    99+
    2024-04-02
  • Golang为何在高并发情境下表现出色?
    Golang为何在高并发情境下表现出色? 随着互联网应用的普及和数据量的不断增加,高并发场景下的稳定性和性能成为了开发者们关注的重点。在这种情况下,Golang(Go)这门编程语言备受...
    99+
    2024-02-29
    golang 并发 高性能 并发访问 并发请求 标准库
  • 主板有问题会出现什么现象
    这篇文章给大家分享的是有关主板有问题会出现什么现象的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。主板有问题会出现的现象:1、开机无显示;2、CMOS设置不能保存;3、安装主板驱动程序后出现死机或光驱读盘速度变慢;...
    99+
    2023-06-14
  • 为什么TypeScript的Enum会出现问题
    目录发生了什么呢?什么时候用控制枚举的数字Bit值控制索引非数字枚举结论TypeScript引入了很多静态编译语言的特性,比如class(现在是JavaScript的一部分了),in...
    99+
    2024-04-02
  • java高并发下脏读问题怎么解决
    在Java高并发下解决脏读问题可以通过使用锁机制或者使用线程安全的数据结构来实现。1. 使用锁机制:可以使用synchronized...
    99+
    2023-08-23
    java
  • Vue2.0中过滤器会出现什么问题
    这篇文章给大家分享的是有关Vue2.0中过滤器会出现什么问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。vue2.0里,不再有自带的过滤器,需要自己定义过滤器。定义的方法如下:...
    99+
    2024-04-02
  • 为什么会出现无权限访问phpmyadmin的问题
    小编给大家分享一下为什么会出现无权限访问phpmyadmin的问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!由于我安装wam...
    99+
    2024-04-02
  • Tomcat 9.0.26高并发场景下DeadLock问题怎么处理
    这篇文章给大家分享的是有关Tomcat 9.0.26高并发场景下DeadLock问题怎么处理的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、Tomcat容器 9.0.26 版本 Deadlock 问题1.1 问...
    99+
    2023-06-04
  • PHP怎么解决高并发问题
    这篇文章主要介绍了PHP怎么解决高并发问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。举个例子,高速路口,1秒钟来5部车,每秒通过5部车,高速路口运作正常。突然,这个路口1...
    99+
    2023-06-15
  • golang高并发问题怎么解决
    在Go语言中,高并发问题可以通过以下几种方式来解决: 使用goroutine:Goroutine是Go语言的轻量级线程,可以并发...
    99+
    2024-02-29
    golang
  • golang出现内存逃逸会导致什么问题
    当Golang程序出现内存逃逸时,会导致以下几个问题: 垃圾回收开销增加:内存逃逸会导致对象分配在堆上,而不是在栈上。这意味着垃...
    99+
    2023-10-26
    golang
  • liunx系统下时钟不同步会出现问题
    这篇文章主要讲解了“liunx系统下时钟不同步会出现问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“liunx系统下时钟不同步会出现问题”吧!linux的系统时钟在很多地方都要用到,要是不...
    99+
    2023-06-13
  • Windows环境下如何解决ASP并发请求出现的问题?
    在Windows环境下,ASP并发请求出现的问题是很常见的。当多个用户同时访问一个ASP应用程序时,这些请求可能会相互干扰,导致应用程序出现异常。这篇文章将介绍如何解决这个问题,让ASP应用程序能够处理更多的并发请求。 一、使用Sessio...
    99+
    2023-08-05
    load 并发 windows
  • 使用香港高防空间会出现哪些问题
    使用香港高防空间会出现的问题有:1、香港高防空间系统重装问题,用户需要注意是否要保留D盘数据;2、香港高防空间远程登录问题,用户可用PING命令测试网络是否连通,若实在解决不了,可咨询技术人员解决;3、香港高防空间更换IP问题,需要具体分析...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作