热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

hashmap死循环,hashmap并发死循环原理

hashmap死循环,hashmap并发死循环原理00-1010预备知识无限循环执行步骤1无限循环执行步骤2无限循环执行步骤3解决方案总结前言:HashMap无限循环是一个常见且经

  hashmap 死循环,hashmap并发死循环原理

  00-1010预备知识无限循环执行步骤1无限循环执行步骤2无限循环执行步骤3解决方案总结前言:

  HashMap无限循环是一个常见且经典的问题,在日常采访中经常出现,下面我们就通过图解的方式带大家彻底了解无限循环产生的原因。

  00-1010 JDK 1.7版本出现了无限循环问题,主要是HashMap本身的运行机制和并发操作导致了无限循环。在JDK 1.7中,HashMap的底层数据实现是数组链表,

  如下图所示:

  而 HashMap 在数据添加时使用的是头插入,如下图所示:

  HashMap 正常情况下的扩容实现如下图所示:

  旧散列表的节点将依次转移到新散列表中。旧HashMap传递的顺序是A,B,C,而新HashMap使用的是head插入法,所以新HashMap中最后的顺序是C,B,A,如上图所示。有了这些预知,我们来看看无限循环是怎么诞生的。

  00-1010无限循环是由并发HashMap扩展引起的。在并发扩展的第一步,线程T1和T2需要扩展HashMap。此时,T1和T2指向链表的头节点元素A,而T1和T2的下一个节点,即T1.next和T2.next,指向节点B,

  如下图所示:

  00-1010无限循环的第二步是线程T2用完时间片并进入睡眠,而线程T1开始执行扩展操作。扩容之后的场景如下图所示:.直到线程T1的扩展完成,线程T2才被唤醒

  从上图可以看出,线程T1执行后,HashMap的顺序因为head插入方法发生了变化,但是线程T2对发生的一切是不可知的,所以它的pointing元素保持不变。如上图所示,T2指向元素A,节点T2.next指向元素b

  

目录

当线程 T1 执行完,而线程 T2 恢复执行时,死循环就建立了,如下图所示:

 

  因为T1扩展后节点B的下一个节点是A,而T2线程指向的第一个节点是A,第二个节点是B,这个顺序正好与T1扩展后节点的顺序相反。T1 执行完之后的顺序是 B 到 A,而 T2 的顺序是 A 到 B,这样 A 节点和 B 节点就形成死循环了,这就是散列表无止境的原因。

  

前置知识

HashMap 死循环的常用解决方案有以下 3 个:

 

  请改用线程安全的容器ConcurrentHashMap(推荐使用这种方案)。请改用线程安全的容器哈希表(低性能,不推荐)。用synchronized或者Lock锁定HashMap,然后操作,相当于多线程排队执行(比较麻烦,不推荐)。

  

死循环执行步骤1

JDK 1.7中出现HashMap无限循环。形成死循环的原因是HashMap使用了JDK 1.7中的头插入方法,头插入方法的链表是多线程的,HashMap是扩展的。这些点共同构成了HashMap的无限循环,可以用线程安全容器ConcurrentHashMap来代替。

 

  关于为什么Java中的HashMap会产生无限循环的文章到此为止。关于HashMap无限循环的更多信息,请搜索popular IT之前的文章或者继续浏览下面的相关文章。我希望你以后能更多地支持流行音乐!



推荐阅读
  • HashTable与ConcurrentHashMap均可实现HashMap的功能,对外提供了键值对存储的数据结构。但是在内部结构及实现上有何区别,性能上的差异到底在哪里又是如何导致的 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • 深入解析CAS机制:全面替代传统锁的底层原理与应用
    本文深入探讨了CAS(Compare-and-Swap)机制,分析了其作为传统锁的替代方案在并发控制中的优势与原理。CAS通过原子操作确保数据的一致性,避免了传统锁带来的性能瓶颈和死锁问题。文章详细解析了CAS的工作机制,并结合实际应用场景,展示了其在高并发环境下的高效性和可靠性。 ... [详细]
  • Java高并发与多线程(二):线程的实现方式详解
    本文将深入探讨Java中线程的三种主要实现方式,包括继承Thread类、实现Runnable接口和实现Callable接口,并分析它们之间的异同及其应用场景。 ... [详细]
  • 在多线程并发环境中,普通变量的操作往往是线程不安全的。本文通过一个简单的例子,展示了如何使用 AtomicInteger 类及其核心的 CAS 无锁算法来保证线程安全。 ... [详细]
  • 本文是Java并发编程系列的开篇之作,将详细解析Java 1.5及以上版本中提供的并发工具。文章假设读者已经具备同步和易失性关键字的基本知识,重点介绍信号量机制的内部工作原理及其在实际开发中的应用。 ... [详细]
  • 在本文中,我们将探讨如何在Docker环境中高效地管理和利用数据库。首先,需要安装Docker Desktop以确保本地环境准备就绪。接下来,可以从Docker Hub中选择合适的数据库镜像,并通过简单的命令将其拉取到本地。此外,我们还将介绍如何配置和优化这些数据库容器,以实现最佳性能和安全性。 ... [详细]
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • Java并发机制详解及其在数据安全性保障中的应用方案 ... [详细]
  • 本文深入探讨了Java多线程环境下的同步机制及其应用,重点介绍了`synchronized`关键字的使用方法和原理。`synchronized`关键字主要用于确保多个线程在访问共享资源时的互斥性和原子性。通过具体示例,如在一个类中使用`synchronized`修饰方法,展示了如何实现线程安全的代码块。此外,文章还讨论了`ReentrantLock`等其他同步工具的优缺点,并提供了实际应用场景中的最佳实践。 ... [详细]
  • 深入浅析JVM垃圾回收机制与收集器概述
    本文基于《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》的阅读心得进行整理,详细探讨了JVM的垃圾回收机制及其各类收集器的特点与应用场景。通过分析不同垃圾收集器的工作原理和性能表现,帮助读者深入了解JVM内存管理的核心技术,为优化Java应用程序提供实用指导。 ... [详细]
  • 本文深入解析了Java 8并发编程中的`AtomicInteger`类,详细探讨了其源码实现和应用场景。`AtomicInteger`通过硬件级别的原子操作,确保了整型变量在多线程环境下的安全性和高效性,避免了传统加锁方式带来的性能开销。文章不仅剖析了`AtomicInteger`的内部机制,还结合实际案例展示了其在并发编程中的优势和使用技巧。 ... [详细]
  • 2012年9月12日优酷土豆校园招聘笔试题目解析与备考指南
    2012年9月12日,优酷土豆校园招聘笔试题目解析与备考指南。在选择题部分,有一道题目涉及中国人的血型分布情况,具体为A型30%、B型20%、O型40%、AB型10%。若需确保在随机选取的样本中,至少有一人为B型血的概率不低于90%,则需要选取的最少人数是多少?该问题不仅考察了概率统计的基本知识,还要求考生具备一定的逻辑推理能力。 ... [详细]
  • android布局基础及范例(二):人人android九宫格布局
    人人android是人人网推出的一款优秀的手机应用软件,我们在使用的时候发现他的首页布局是九宫格模式的,让人觉得很别致,因为现在很多的android软件很少使用这种布局模式,人人andr ... [详细]
  • Java集合详解5:深入理解LinkedHashMap和LRU缓存
    Java集合详解5:深入理解LinkedHashMap和LRU缓存今天我们来深入探索一下LinkedHashMap的底层原理,并且使用linkedhashmap来实现LRU缓存。具体代码在我的 ... [详细]
author-avatar
这个昵称能用嘛
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有