Java - ConcurrentHashMap的原理
Java - ConcurrentHashMap的原理
**这是JDK1.7的实现**
ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment。
HashEntry 用来封装映射表的键 / 值对;Segment 用来充当锁的角色,每个 Segment 对象守护整个散列映射表的若干个桶。每个桶是由若干个 HashEntry 对象链接起来的链表。
一个 ConcurrentHashMap 实例中包含由若干个 Segment 对象组成的数组。HashEntry 用来封装散列映射表中的键值对。
在 HashEntry 类中,key,hash 和 next 域都被声明为 final 型,value 域被声明为 volatile 型。
Segment --->桶(bucket)--->HashEntry
static final class HashEntry<K,V> {
final K key; // 声明 key 为 final 型
final int hash; // 声明 hash 值为 final 型
volatile V value; // 声明 value 为 volatile 型
final HashEntry<K,V> next; // 声明 next 为 final 型
HashEntry(K key, int hash, HashEntry<K,V> next, V value) {
this.key = key;
this.hash = hash;
this.next = next;
this.value = value;
}
}
在ConcurrentHashMap 中,在散列时如果产生“碰撞”,将采用“分离链接法(链表法)”来处理“碰撞”:把“碰撞”的 HashEntry 对象链接成一个链表。由于 HashEntry 的 next 域为 final 型,所以新节点只能在链表的表头处插入。 下图是在一个空桶中依次插入 A,B,C 三个 HashEntry 对象后的结构图:
图1. 插入三个节点后桶的结构示意图:

注意:由于只能在表头插入,所以链表中节点的顺序和插入的顺序相反。
Segment 类继承于 ReentrantLock 类,从而使得 Segment 对象能充当锁的角色。每个 Segment 对象用来守护其(成员对象 table 中)包含的若干个桶。
Concurrenthashmap线程安全的,1.7是在jdk1.7中采用Segment + HashEntry的方式进行实现的,lock加在Segment上面。1.7size计算是先采用不加锁的方式,连续计算元素的个数,最多计算3次:
1、如果前后两次计算结果相同,则说明计算出来的元素个数是准确的;
2、如果前后两次计算结果都不同,则给每个Segment进行加锁,再计算一次元素的个数;
1.8中放弃了Segment臃肿的设计,取而代之的是采用Node + CAS + Synchronized来保证并发安全进行实现,1.8中使用一个volatile类型的变量baseCount记录元素的个数,当插入新数据或则删除数据时,会通过addCount()方法更新baseCount,通过累加baseCount和CounterCell数组中的数量,即可得到元素的总个数;
Java - ConcurrentHashMap的原理的更多相关文章
- Java ConcurrentHashMap
通过分析Hashtable就知道,synchronized是针对整张Hash表的,即每次锁住整张表让线程独占, ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术. ...
- ConcurrentHashMap实现原理及源码分析
ConcurrentHashMap实现原理 ConcurrentHashMap源码分析 总结 ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对Ha ...
- HashMap和ConcurrentHashMap实现原理及源码分析
HashMap实现原理及源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表, ...
- ConcurrentHashMap实现原理
ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对HashMap的实现原理还不甚了解,可参考我的另一篇文章HashMap实现原理及源码分析),Con ...
- Java LinkedHashMap工作原理及实现
Java LinkedHashMap工作原理及实现 原文出处: Yikun 1. 概述 在理解了#7 介绍的HashMap后,我们来学习LinkedHashMap的工作原理及实现.首先还是类似的,我们 ...
- Java ConcurrentHashMap 源代码分析
Java ConcurrentHashMap jdk1.8 之前用到过这个,但是一直不清楚原理,今天抽空看了一下代码 但是由于我一直在使用java8,试了半天,暂时还没复现过put死循环的bug 查了 ...
- Java面向切面原理与实践
Java面向切面原理与实践 一. 面向切面编程是什么 首先用一句话概括:面向切面编程(AOP)就是对某些具有相似点的代码进行增强. 相似点可以是同一个包.使用相同的注解.public的方法.以Impl ...
- 嘿嘿,我就知道面试官接下来要问我 ConcurrentHashMap 底层原理了,看我怎么秀他
前言 上篇文章介绍了 HashMap 源码后,在博客平台广受好评,让本来己经不打算更新这个系列的我,仿佛被打了一顿鸡血.真的,被读者认可的感觉,就是这么奇妙. 然后,有读者希望我能出一版 Concur ...
- Java ConcurrentHashMap Example and Iterator--转
原文地址:http://www.journaldev.com/122/java-concurrenthashmap-example-iterator#comment-27448 Today we wi ...
随机推荐
- Android修改app图标
1.按照路径找到AndroidManifest.xml中的icon 2.在drawable添加一个png图片 3.然后在AndroidManifest.xml中的icon,修改其中的值 android ...
- cannot find module providing package github.com/× working directory is not part of a module
今天在搭建fabric的过程中遇到一个问题,记录一下 root@zitao /home/hong/Desktop/gowork/src/github.com/hyperledger/fabric re ...
- Java学习day13
泛型类格式: 修饰符 class 类名<类型>{ } 常用T.E.K.V等形式的参数表示泛型 使用方式与C++的类模板相似,在创建对象时要明确数据类型 泛型方法定义格式: 修饰符<类 ...
- vue3跳转路由3步曲
import { useRouter } from 'vue-router'; // 1. 引入路由export default { setup() { const $router ...
- 想要白嫖ppt?记住这几个网站就够了
良心ppt,超赞! [PPT]:OfficePlushttps://www.officeplus.cn/Template/Home.shtml稻壳Docerhttps://www.docer.com/ ...
- 【Azure Developer】使用 CURL 获取 Key Vault 中 Secrets 中的值
问题描述 在使用CURL通过REST API获取Azure Key Vaualt的Secrets值,提示Missing Token, 问如何来生成正确的Token呢? # curl 命令 curl - ...
- Kernel pwn 基础教程之 Heap Overflow
一.前言 在如今的CTF比赛大环境下,掌握glibc堆内存分配已经成为了大家的必修课程.然而在内核态中,堆内存的分配策略发生了变化.笔者会在介绍内核堆利用方式之前先简单的介绍一下自己了解的内核内存分配 ...
- XCTF练习题---MISC---glance-50
XCTF练习题---MISC---glance-50 flag:TWCTF{Bliss by Charles O'Rear} 解题步骤: 1.观察题目,下载附件 2.下载完成以后,隐隐约约像是一张动图 ...
- Protobuf在Python中的应用(序列化数据)
1.了解Protobuf Protocol Buffer是Google的语言中立的,平台中立的,可扩展机制的,用于序列化结构化数据 - 对比XML,但更小,更快,更简单.您可以定义数据的结构化,然后可 ...
- [题解][P5206][WC2019] 数树 (op = 1)
简要题意 给定 \(n, y\). 一张图有 \(|V| = n\) 个点,现在给出两棵树 \(T_1=G(V, E_1)\) 和 \(T_2=G(V, E_2)\). 定义这两棵树的权值 \(F(E ...