我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ConcurrentHashMap的实现原理是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

ConcurrentHashMap的实现原理是什么

这篇文章将为大家详细讲解有关ConcurrentHashMap的实现原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

1.HashTable与ConcurrentHashMap的对比

HashTable本身是线程安全的,写过Java程序的都知道通过加Synchronized关键字实现线程安全,这样对整张表加锁实现同步的一个缺陷就在于使程序的效率变得很低。这就是为什么Java中会在1.5后引入ConcurrentHashMap的原因。

ConcurrentHashMap的实现原理是什么

从图中可以看出,HashTable的锁加在整个Hash表上,而ConcurrentHashMap将锁加在segment上(每个段上),这样我们在对segment1操作的时候,同时也可以对segment2中的数据操作,这样效率就会高很多。

2.ConcurrentHashMap的内部结构

ConcurrentHashMap的实现原理是什么

ConcurrentHashMap主要有三大结构:整个Hash表,segment(段),HashEntry(节点)。每个segment就相当于一个HashTable。

(1)HashEntry类

每个HashEntry代表Hash表中的一个节点,在其定义的结构中可以看到,除了value值没有定义final,其余的都定义为final类型,我们知道Java中关键词final修饰的域成为最终域。用关键词final修饰的变量一旦赋值,就不能改变,也称为修饰的标识为常量。这就意味着我们删除或者增加一个节点的时候,就必须从头开始重新建立Hash链,因为next引用值需要改变。

ConcurrentHashMap的实现原理是什么

由于这样的特性,所以插入Hash链中的数据都是从头开始插入的。例如将A,B,C插入空桶中,插入后的结构为:
ConcurrentHashMap的实现原理是什么

(2)segment类

Segment 类继承于 ReentrantLock 类,从而使得 Segment 对象能充当锁的角色。每个 Segment 对象用来守护其(成员对象 table 中)包含的若干个桶。

table 是一个由 HashEntry 对象组成的数组。table 数组的每一个数组成员就是散列映射表的一个桶。

count 变量是一个计数器,它表示每个 Segment 对象管理的 table 数组(若干个 HashEntry 组成的链表)包含的 HashEntry 对象的个数。每一个 Segment 对象都有一个 count 对象来表示本 Segment 中包含的 HashEntry 对象的总数。注意,之所以在每个 Segment 对象中包含一个计数器,而不是在 ConcurrentHashMap 中使用全局的计数器,是为了避免出现“热点域”而影响 ConcurrentHashMap 的并发性。

ConcurrentHashMap的实现原理是什么

ConcurrentHashMap 类

默认的情况下,每个ConcurrentHashMap 类会创建16个并发的segment,每个segment里面包含多个Hash表,每个Hash链都是有HashEntry节点组成的。

ConcurrentHashMap的实现原理是什么

3.用分离锁实现多个线程间的并发写操作
(1)Put方法的实现

ConcurrentHashMap的实现原理是什么

ConcurrentHashMap的实现原理是什么

整个代码通过注释很好理解了,稍微要注意的是这里的加锁是针对具体的segment,而不是对整个ConcurrentHashMap。Put方法从源码上可以看出是从链表的头部插入新的数据的。

(2)Get方法的实现

ConcurrentHashMap的实现原理是什么

ConcurrentHashMap中的读方法不需要加锁,所有的修改操作在进行结构修改时都会在最后一步写count 变量,通过这种机制保证get操作能够得到几乎最新的结构更新。

(3)Remove方法的实现

ConcurrentHashMap的实现原理是什么

整个操作是在持有段锁的情况下执行的,空白行之前的行主要是定位到要删除的节点e。接下来,如果不存在这个节点就直接返回null,否则就要将e前面的结点复制一遍,尾结点指向e的下一个结点。e后面的结点不需要复制,它们可以重用。

中间那个for循环是做什么用的呢?从代码来看,就是将定位之后的所有entry克隆并拼回前面去,但有必要吗?每次删除一个元素就要将那之前的元素克隆一遍?这点其实是由entry的不变性来决定的,仔细观察entry定义,发现除了value,其他所有属性都是用final来修饰的,这意味着在第一次设置了next域之后便不能再改变它,取而代之的是将它之前的节点全都克隆一次。至于entry为什么要设置为不变性,这跟不变性的访问不需要同步从而节省时间有关。

执行删除之前的原链表:
ConcurrentHashMap的实现原理是什么

执行删除之后的新链表
ConcurrentHashMap的实现原理是什么

注意:新链表在clone的时候。顺序发生反转,A->B变为B->A。

(4)containsKey方法的实现

containsKey方法操作相对简单,因为它不需要读取值。

ConcurrentHashMap的实现原理是什么

4.总结

在使用锁来协调多线程间并发访问的模式下,减小对锁的竞争可以有效提高并发性。有两种方式可以减小对锁的竞争:

  • 减小请求同一个锁的频率。

  • 减少持有锁的时间。

ConcurrentHashMap 的高并发性主要来自于三个方面:

  • 用分离锁实现多个线程间的更深层次的共享访问。

  • 用 HashEntery 对象的不变性来降低执行读操作的线程在遍历链表期间对加锁的需求。

  • 通过对同一个 Volatile 变量的写 / 读访问,协调不同线程间读 / 写操作的内存可见性。

使用分离锁,减小了请求同一个锁的频率。

concurrentHashMap在jdk1.8中主要做了2方面的改进

改进一:取消segments字段,直接采用transient volatile HashEntry<K,V>[] table保存数据,采用table数组元素作为锁,从而实现了对每一行数据进行加锁,进一步减少并发冲突的概率。

改进二:将原先table数组+单向链表的数据结构,变更为table数组+单向链表+红黑树的结构。对于hash表来说,最核心的能力在于将key hash之后能均匀的分布在数组中。如果hash之后散列的很均匀,那么table数组中的每个队列长度主要为0或者1。但实际情况并非总是如此理想,虽然ConcurrentHashMap类默认的加载因子为0.75,但是在数据量过大或者运气不佳的情况下,还是会存在一些队列长度过长的情况,如果还是采用单向列表方式,那么查询某个节点的时间复杂度为O(n);因此,对于个数超过8(默认值)的列表,jdk1.8中采用了红黑树的结构,那么查询的时间复杂度可以降低到O(logN),可以改进性能。

关于ConcurrentHashMap的实现原理是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

ConcurrentHashMap的实现原理是什么

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

下载Word文档

猜你喜欢

ConcurrentHashMap的实现原理是什么

这篇文章将为大家详细讲解有关ConcurrentHashMap的实现原理是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1.HashTable与ConcurrentHashMap的对比H
2023-06-19

Java8中ConcurrentHashMap的原理是什么

这期内容当中小编将会给大家带来有关Java8中ConcurrentHashMap的原理是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序
2023-06-14

chatgpt的实现原理是什么

本文小编为大家详细介绍“chatgpt的实现原理是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“chatgpt的实现原理是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。chatgpt的原理ChatGPT
2023-02-21

SSH的实现原理是什么

本篇内容介绍了“SSH的实现原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!SSH是一种协议标准,它的主要目的是实现远程登录和提供安
2023-06-17

hooks的实现原理是什么

Hooks是React 16.8版本引入的一种新特性,它可以让我们在不编写class的情况下使用state和其他React的特性。Hooks的实现原理主要有两个方面:1. 使用链表来保存组件的状态:在React内部,使用一个链表来保存每个组
2023-10-10

sync.Pool的实现原理是什么

本篇内容主要讲解“sync.Pool的实现原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“sync.Pool的实现原理是什么”吧!sync.Pool实现原理对象的创建和销毁会消耗一定的系
2023-06-19

CountDownLatch的实现原理是什么

这篇文章主要讲解了“CountDownLatch的实现原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“CountDownLatch的实现原理是什么”吧! 前言CountDownLat
2023-06-15

Linux的实现原理是什么

本篇内容主要讲解“Linux的实现原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Linux的实现原理是什么”吧!1 引言90年代以来,数控技术发展的一个重要趋势是数控系统的开放化。目前
2023-06-16

vuex的实现原理是什么

本篇内容主要讲解“vuex的实现原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vuex的实现原理是什么”吧!关于vuex就不再赘述,简单回顾一下:当应用碰到多个组件共享状态时,简单的单
2023-07-05

java原子类实现的原理是什么

Java原子类的实现原理是利用了底层的CAS(Compare and Swap)操作。CAS是一种乐观锁机制,它包含三个参数:内存位置V,旧的预期值A和新的值B。CAS操作首先将内存位置V的值与预期值A进行比较,如果相等,则将内存位置V的值
2023-10-18

Java AQS的实现原理是什么

这篇文章主要介绍“Java AQS的实现原理是什么”,在日常操作中,相信很多人在Java AQS的实现原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java AQS的实现原理是什么”的疑惑有所帮助!
2023-07-05

golang select的实现原理是什么

在Go语言中,`select`语句用于从多个通道中接收数据,并且只有当其中一个通道可以接收数据时,`select`语句才会执行相应的代码块。`select`语句的实现原理是通过轮询的方式来监听通道的状态。当`select`语句执行时,它会
2023-10-27

Vue-Router的实现原理是什么

这篇文章主要介绍“Vue-Router的实现原理是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue-Router的实现原理是什么”文章能帮助大家解决问题。路由既然我们在分析路由,我们首先来说
2023-07-04

NotificationCenter类的实现原理是什么

这篇文章主要讲解了“NotificationCenter类的实现原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“NotificationCenter类的实现原理是什么”吧!正文Not
2023-07-05

java lock的实现原理是什么

Java中的锁(Lock)是一种同步机制,用于控制多个线程对共享资源的访问。锁的主要作用是确保在同一时刻只有一个线程能够访问某个共享资源,从而防止数据竞争和线程安全问题的发生。Java中的锁主要有两种实现原理:内置锁(synchronize
2023-10-20

Docker exec的实现原理是什么

本篇内容主要讲解“Docker exec的实现原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Docker exec的实现原理是什么”吧!我使用了 docker exec 命令进入到了容
2023-06-29

golang锁的实现原理是什么

golang锁的实现原理是通过互斥锁和读写锁来保护共享资源的访问。互斥锁是一种基本的锁机制,用于保护共享资源,使用一个标志位来表示资源是否被占用,当一个goroutine获取到互斥锁后,其他goroutine就会被阻塞,直到该gorouti
golang锁的实现原理是什么
2023-12-12

mysql driver的实现原理是什么

MySQL驱动的实现原理是通过与MySQL数据库进行通信来实现与数据库的连接和操作。具体来说,MySQL驱动使用Socket来与MySQL服务器建立连接,并通过使用MySQL的协议来与服务器进行数据交互。驱动会发送SQL语句给服务器,并接
mysql driver的实现原理是什么
2024-04-09

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录