ConcurrentHashMap
主要两个结构:Segment[] 和 HashEntry[]
每个Segment是一个ReentrantLock
Segment结构跟HashMap差不多,成员:table,count,loadFactor,threshold,modCount
每个Segment继承ReentrantLock,实现Serializable
定义了一般的map方法,get,put,clear,containsKey,containsValue,replace,rehash
table里面是HashEntry,成员key,value,next,hash
找Segment的index,hash(object.hashCode()),index = (hash>>>sigmentShift(28))&segmentMask(16)
找HashEntry的index,index = (hash & tab.length-1)
总结:找Segment利用的是hash值的高四位,找Entry利用的是hash值的低四位,所以还有中间24位都没有用到
get 不加锁,只有在发现当hash值和key等相等,但value是null,才会加锁(readValueUnderLock),保证value的读取。
因为new出来的Entry是赋值给table里面的,虽然table是volatile,但里面的元素的赋值不是,所以就有可能出现引用和初始化被重排序,导致读到的value是null的现象,所以只能加锁避免。(跟是不是new JMM没关系)
put 整个过程加锁。遍历entry链,如果key存在相同,覆盖旧的value(hashEntry类里只有value不是final的)
如果不存在,new HashEntry,将first设置为它的next,将新entry设置到数组table相应的位置
rehash
小优化:预先遍历一个bucket里面的entry,找到最末尾连续的一段新索引(lastIdx)都相同的链表,将它们直接设置到新的数组位置
这里不用担心"直接"赋值会不会覆盖数据,因为每次都是扩充2倍,算法上是不会出现这种情况
剩余的entry就需要一个一个创建新entry放到各自不同的数组位置
remove
保留要删除的entry后面的链表,将该entry之前的节点重新创建一遍,从first开始遍历,导致前面一段的顺序反转了
JDK7对ConcurrentHashMap进行改进
get 抛弃掉判断null再加锁方式,而是用unsafe工具的getObjectVolatile方式来读数组里的元素
put 先去tryLock(自旋),如果不能获得锁,执行
scanAndLockForPut
加入了自旋(tryLock)的机制,自旋一定次数(MAX_SCAN_RETRIES 默认64)后执行lock。
自旋过程中会检查entry链的first是否有变化,如果有变化,重新从新的first开始遍历,retires设置为-1
返回HashEntry,在获取锁之前,可以先找到要替换或者是创建要插入的新entry
remove
不再重新创建要删除节点之前的链表,而是直接做最简单的pred.next=next。利用了系统底层级别的缓存特性。保证了读线程的并发正确性
所以entry中的next从final变成了volatile
相关推荐
### Java源码剖析-ConcurrentHashMap #### 一、概述 `ConcurrentHashMap`是Java并发包(`java.util.concurrent`)中的一个重要组成部分,它提供了一个线程安全的哈希表实现。与传统的`Hashtable`相比,`...
java本地缓存ConcurrentHashMap
Java并发编程中的ConcurrentHashMap是HashMap的一个线程安全版本,设计目标是在高并发场景下提供高效的数据访问。相比HashTable,ConcurrentHashMap通过采用锁分离技术和更细粒度的锁定策略来提升性能。HashTable...
在JDK 1.8版本中,`ConcurrentHashMap`中的`computeIfAbsent`方法存在一个潜在的死循环问题。这个bug主要出现在并发操作时,当`ConcurrentHashMap`需要进行扩容并且`computeIfAbsent`正在执行计算的过程中,可能会...
Java利用ConcurrentHashMap实现本地缓存demo; 基本功能有缓存有效期、缓存最大数、缓存存入记录、清理线程、过期算法删除缓存、LRU算法删除、获取缓存值等功能。 复制到本地项目的时候,记得改包路径哦~
在Java编程语言中,`HashMap`和`ConcurrentHashMap`是两种非常重要的数据结构,它们都属于`java.util`包,用于存储键值对。本文将深入解析这两个类在Java 7和8版本中的实现原理、特点以及使用场景。 首先,`HashMap...
ConcurrentHashMap#put方法源码解析 ConcurrentHashMap是Java并发编程中的一个重要组件,用于解决高并发情况下的数据存储问题。在面试中,ConcurrentHashMap的底层原理、put方法的实现细节都是高频考点。本文将对...
在Java 7和8中,HashMap和ConcurrentHashMap是两种重要的数据结构,分别用于非线程安全和线程安全的键值对存储。本篇文章将深入解析这两种数据结构的内部实现,帮助读者理解它们的工作原理。 HashMap是Java中最常用...
`ConcurrentHashMap`是Java并发编程中非常重要的一个数据结构,它是线程安全的HashMap实现。在理解`ConcurrentHashMap`的实现原理之前,我们先来看看哈希表的基本概念。 哈希表是一种键值对存储的数据结构,通过键...
### ConcurrentHashMap源码剖析 #### 一、概述与背景 ConcurrentHashMap是Java中提供的一种高效、线程安全的哈希表实现。与传统的基于synchronized关键字实现线程安全的HashTable相比,ConcurrentHashMap通过采用...
在Java并发编程中,ConcurrentHashMap是一个重要的并发集合。它是由Doug Lea在JSR166y中引入,并在Java 5中提供的一种线程安全的HashMap实现。与传统的HashMap相比,ConcurrentHashMap在多线程环境下具有更好的性能...
程序员面试加薪必备_ConcurrentHashMap底层原理与源码分析深入详解
ConcurrentHashMap 的实现原理 ConcurrentHashMap 是 Java 中一个高效的线程安全的哈希表实现,它的实现原理可以分为两部分:JDK1.7 中的实现和 JDK8 中的实现。 JDK1.7 中的实现 在 JDK1.7 中,...
在Java的并发编程中,ConcurrentHashMap 是一个非常重要的组件,它提供了线程安全的HashMap实现。本文将深入探讨 ConcurrentHashMap 的内部实现原理,并通过代码示例展示其使用方法和优势。 通过本文,我们深入探讨...
### Java并发编程之ConcurrentHashMap #### 一、概述 `ConcurrentHashMap`是Java并发编程中的一个重要组件,它提供了一种线程安全的哈希表实现方式。与传统的`Hashtable`或`synchronized`关键字相比,`...
ConcurrentHashMap是J.U.C(java.util.concurrent包)的重要成员,它是HashMap的一个线程安全的、支持高效并发的版本。在默认理想状态下,ConcurrentHashMap可以支持16个线程执行并发写操作及任意数量线程的读操作。...
【标题】"ConcurrentHashMap共18页.pdf.zip" 提供的资料主要聚焦于Java并发编程中的重要数据结构——`ConcurrentHashMap`。这个压缩包包含了一份18页的PDF文档,很可能详细阐述了`ConcurrentHashMap`的设计原理、...