首页 > 其他分享 >HashMap和ConcurrentHashMap的底层实现原理

HashMap和ConcurrentHashMap的底层实现原理

时间:2024-07-10 20:42:23浏览次数:17  
标签:ConcurrentHashMap 加锁 HashMap 链表 数组 Segment 底层

(1)HashMap底层实现原理

JDK 1.7 版本之前, HashMap 数据结构是数组和链表,HashMap 通过哈希算法将元素的键 (Key) 映射到数组中的槽位 (Bucket)。如果多个键映射到同一个槽位,它们会以链表的形式存储在同一个槽位上,因为链表的查询时间是 O(n),所以冲突很严重,一个索引上的链表非常长,效率就很低了。

 所以在 JDK 1.8 版本的时候做了优化,当一个链表的长度超过8的时候就转换数据结构,不再使用链表存储,而是使用红黑树,查找时使用红黑树,时间复杂度 O(logn),可以提高查询性能,但是在数量较少时,即数量小于6时,会将红黑树转换回链表。

 

(2)ConcurrentHashMap

JDK1.7 中它使用的是数组加链表的形式实现的,而数组又分为:大数组 Segment 和小数组 HashEntry。Segment 是一种可重入锁 (ReentrantLock),在 ConcurrentHashMap 里扮演锁的角色;HashEntry 则用于存储键值对数据。一个 ConcurrentHashMap 里包含一个 Segment 数组,一个 Segment 里包含一个 HashEntry 数组,每个 HashEntry 是一个链表结构的元素。简单理解就是,ConcurrentHashMap 是一个 Segment 数组,Segment 通过继承 ReentrantLock 来进行加锁,所以每次需要加锁的操作锁住的是一个 Segment,这样只要保证每个 Segment 是线程安全的,也就实现了全局的线程安全。

JDK1.8 也引入了红黑树,优化了之前的固定链表,那么当数据量比较大的时候,查询性能也得到了很大的提升,从之前的 O(n) 优化到了 O(logn) 的时间复杂度。ConcurrentHashMap 主要通过 volatile + CAS 或者 synchronized 来实现的线程安全的,ConcurrentHashMap 通过对头结点加锁来保证线程安全的,锁的粒度相比 Segment 来说更小了,发生冲突和加锁的频率降低了,并发操作的性能就提高了。

 

标签:ConcurrentHashMap,加锁,HashMap,链表,数组,Segment,底层
From: https://www.cnblogs.com/kenwan/p/18294954

相关文章

  • [Java基础]HashMap
    HashMapHashMap的数据结构HashMap是:数组+链表/红黑树(JDK1.8增加了红黑树部分)数据底层具体存储的是什么?Node<k,v>这样的存储方式有什么优点呢?数据结构//默认初始容量(数组默认大小):16,2的整数次方staticfinalintDEFAULT_INITIAL_CAPACITY=1<<4;//最大......
  • C++数据结构底层实现算法
    1.vector底层数据结构为数组,支持快速随机访问2.list底层数据结构为双向链表,支持快速增删3.deque底层数据结构为一个中央控制器和多个缓冲区,详细见STL源码剖析P146,支持首尾(中间不能)快速增删,也支持随机访问deque是一个双端队列(double-endedqueue),也是在堆中保存内容的.每个......
  • HashMap和ConcurrentHashMap对比源码分析
    1.1HashMap分析1.1.1JDK7的HashMap HashMap在日常开发中是很常见的,在JDK7中其底层是由数组+链表构成,数组被分成一个个桶(bucket),通过哈希值决定了键值对在这个数组中的位置。哈希值相同的键值对,会以链表形式进行存储。每一个键值对会以一个Entry实例进行封装,内部存在四个......
  • Optimize-Volume 命令用于优化指定驱动器的性能。除了 -Defrag 参数以外,还有一些其他
    Optimize-Volume命令起源于Microsoft的PowerShell环境中的一个磁盘优化工具。它主要用于对磁盘驱动器执行优化操作,包括碎片整理、TRIM操作(针对固态硬盘)、分块整理等。这些操作有助于提高磁盘性能和延长硬件寿命,特别是对于使用频繁的系统和数据驱动器来说尤为重要。在Power......
  • “只讲干货!!”{java入门篇} 勇闯java的勇士们 别问我java行不行 不行也是你不行,不努力
    面向对象编程(Object    Oriented    Programing)神速熟悉面向对象        学完本节,如果还有点糊涂,很正常,本节仅是你的“初恋对象”。本节仅仅是为了方便大家入门,更快的了解面向对象。后面,才是真正开始“面向对象”,真正为了“结婚”、为了“开......
  • 站在架构师角度:深入剖析Spring事务管理底层原理
    摘要Spring框架的事务管理是企业级应用开发中的一个核心特性,它为不同的事务使用场景提供了统一的抽象和实现。本文从架构师的角度出发,深入探讨Spring事务管理的底层原理,包括其设计哲学、核心组件、以及事务传播行为等。1.事务管理概述事务是数据库操作中的一个基本概念,它保......
  • Golang channel底层是如何实现的?(深度好文)
    Hi你好,我是k哥。大厂搬砖6年的后端程序员。我们知道,Go语言为了方便使用者,提供了简单、安全的协程数据同步和通信机制,channel。那我们知道channel底层是如何实现的吗?今天k哥就来聊聊channel的底层实现原理。同时,为了验证我们是否掌握了channel的实现原理,本文也收集了channel的高......
  • ArrayList底层结构和源码分析
    //无参构造器创建ArrayList对象//ArrayListlist=newArrayList();//断点1ArrayListlist=newArrayList(8);//断点2//添加1-10数据for(inti=0;i<=10;i++){list.add(i);}//添......
  • DDR3 SDRAM 底层逻辑
    一.DDR3SDRAM1.基本介绍DDR3SDRAM英文全称“Double-Data-RateThreeSynchronousDynamicRandomAccessMemory”,译为“第三代双倍速率同步动态随机存取内存”或“同步动态随机存储器”,是动态随机存储器(DynamicRandomAccessMemory,简称DRAM)家族的一份子。同步、动......
  • HashMap的插入及扩容过程(必看)
    1.初始化当我们创建一个HashMap实例时,初始化过程如下:Map<Integer,String>map=newHashMap<>();在初始化时,HashMap进行以下操作:默认容量和加载因子:默认容量为16。默认加载因子为0.75。临界值(Threshold):临界值=容量*加载因子,即16*0.75=12。这意味着当......