ConcurrentHashMap底层具体实现以及实现原理


问题描述

ConcurrentHashMap 底层具体实现以及实现原理


分析维度:

1. ConcurrentHashMap的整体架构

2. ConcurrentHashMap的基本功能

3. ConcurrentHashMap在性能方面的优化


解决方案:

  • ConcurrentHashMap 的整体架构

        如图所示,这个是 ConcurrentHashMap 在 JDK1.8 中的存储结构,它是由数组、 单向链表、红黑树组成。

        当我们初始化一个ConcurrentHashMap实例时,默认会初始化一个长度为16的数组。 由于 ConcurrentHashMap 它的核心仍然是 hash 表,所以必然会存在 hash 冲突问题。         ConcurrentHashMap 采用链式寻址法来解决 hash 冲突。 当 hash 冲突比较多的时候,会造成链表长度较长,这种情况会使得 ConcurrentHashMap 中数据元素的查询复杂度变成 O(n)。因此在 JDK1.8 中,引入了 红黑树的机制。

        当数组长度大于 64 并且链表长度大于等于 8 的时候,单项链表就会转换为红黑树。 另外,随着 ConcurrentHashMap 的动态扩容,一旦链表长度小于 8,红黑树会退化成单向链表。

  • ConcurrentHashMap 的基本功能

        ConcurrentHashMap 本质上是一个 HashMap,因此功能和 HashMap 一样,但是 ConcurrentHashMap 在 HashMap 的基础上,提供了并发安全的实现。 并发安全的主要实现是通过对指定的 Node 节点加锁,来保证数据更新的安全性(如图 所示)。

  • ConcurrentHashMap 在性能方面做的优化

        如果在并发性能和数据安全性之间做好平衡,在很多地方都有类似的设计,比如 cpu 的三级缓存、mysql 的 buffer_pool、Synchronized 的锁升级等等。

        ConcurrentHashMap 也做了类似的优化,主要体现在以下几个方面:

                a、 在 JDK1.8 中,ConcurrentHashMap 锁的粒度是数组中的某一个节点,而在                       JDK1.7,锁定的是 Segment(片段),锁的范围要更大,因此性能上会更低。

                b、引入红黑树,降低了数据查询的时间复杂度,红黑树的时间复杂度是 O(logn)。

消耗的时间从小到大

O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)

                c、(如图所示),当数组长度不够时,ConcurrentHashMap 需要对数组进行扩容,

                        在  扩容的实现上,ConcurrentHashMap 引入了多线程并发扩容的机制, 简单来说

                        就是多个线程对原始数组进行分片后,每个线程负责一个分片的数据迁移,从而提

                        升了扩容过程中数据迁移的效率。

               

                d、ConcurrentHashMap 中有一个 size()方法来获取总的元素个数,而在多线程并发场                        景中,在保证原子性的前提下来实现元素个数的累加,性能是非常低的。                                          ConcurrentHashMap 在这个方面的优化主要体现在两个点:

  •  当线程竞争不激烈时,直接采用 CAS(乐观锁) 来实现元素个数的原子递增。
  • 如果线程竞争激烈,使用一个数组来维护元素个数,如果要增加总的元素个数,则直接从数组中随机选择一个,再通过 CAS 实现原子递增。它的核心思想是引入了数组来实现对并发更新的负载。

        

最后

        从以上看到,ConcurrentHashMap 里面有很多设计思想值得学习和借鉴。 比如锁粒度控制、分段锁的设计等,它们都可以应用在实际业务场景中。

        当有足够的积累之后,会发现从这些技术底层的设计思想中能够获得很多设计思路。

                

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/17147.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

清风数学建模——层次分析法

层次分析法 文章目录 层次分析法评价类问题可以用打分来解决1.通过查阅资料选定指标2.画出权重表格并填写2.1.判断矩阵一致矩阵2.3一致性检验的步骤先算一致性指标CI根据表格查找n对应的RI&#xff08;平均随机一致性指标&#xff09;&#xff0c;表格一般会在题目中给出计算一…

3 PostGIS基础查询

PostGIS 基础查询 数据库维护 ps aux | grep postgrespsql 使用命令登录数据库psql -U postgres -d testdb -h localhost -p 5432postgres用户名&#xff0c;testdb数据库名称&#xff0c;localhost ip地址&#xff0c;可以省略&#xff0c;5432端口&#xff0c;可以省略。 …

【iOS】—— UIKit相关问题

文章目录 UIKit常用的UIKit组件懒加载的优势 CALayer和UIView区别关系 UITableViewUITableView遵循的两个delegate以及必须实现的方法上述四个必须实现方法执行顺序其他方法的执行顺序&#xff1a; UICollectionView和UITableView的区别UICollectionViewFlowLayout和UICollecti…

uniapp scroll-view显示滚动条

在style中添加样式&#xff1a; ::v-deep ::-webkit-scrollbar {/* 滚动条整体样式 */display: block;width: 10rpx !important;height: 10rpx !important;-webkit-appearance: auto !important;background: transparent;overflow: auto !important;}::v-deep ::-webkit-scroll…

oracle rman不能自动删除归档日志备份解决

发现在日常备份中&#xff0c;rman无法将过期的归档日志备份删除&#xff0c;查相关资料&#xff0c; delete noprompt backup completed before sysdate-2; 可通过该语句将所有备份记录删除&#xff0c;包括归档日志备份。 整理的脚本如下&#xff1a; 10 20 * * * su - or…

【Java】详解volatile和synchronized关键字

volatile和synchronized都是Java中用于控制并发的关键字&#xff0c;但是它们的使用场景和原理是不同的。 volatile关键字&#xff1a; 特点&#xff1a;volatile关键字主要有两个特性&#xff1a;保证变量的可见性和防止指令重排。当一个共享变量被volatile修饰时&#xff0c…

大数据Flink(五十一):Flink的引入和Flink的简介

文章目录 Flink的引入和Flink的简介 一、Flink的引入 1、第1代——Hadoop MapReduce

CentOS 8 服务器安装 MySQL 报错:no match mysql-community-server

参考 MySQL 官方文档&#xff1a; Re: No match for argument: mysql-community-serverMySQL yum 安装文档 报错如下&#xff1a; 1.No match for argument: mysql-community-server 2.Error: Unable to find a match: mysql-community-server上面的错误都提示找不到 mysql-…

RK809 电源管理芯片配置3-RK3568

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言RK809 芯片概述认识DCDC和LDORK809的引脚RK809 的功能电源管理的概念配置内核驱动电源域IO 电源域配置方法前言 前面提到编译的时候需要正确配置电源,RK3568的电源管理芯片是RK809,下面就来…

MyBatis 核心组件 —— Configuration

概述 Mybatis 的核心组件如下所示&#xff1a; Configuration&#xff1a;用于描述 MyBatis 的主配置信息&#xff0c;其他组件需要获取配置信息时&#xff0c;直接通过 Configuration 对象获取。除此之外&#xff0c;MyBatis 在应用启动时&#xff0c;将 Mapper 配置信息、类…

精选算法题(4)——字符串比较

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 题目描述&#xff1a; 好久没做题目了&#xff0c;近期刷抖音碰到一个题目&#xff0c;乍一看不是很难&#xff0c;但是手生了&a…

HTTP——HTTP报文内的HTTP信息

HTTP 通信过程包括从客户端发往服务器端的请求及从服务器端返回客户端的响应。本章就让我们来了解一下请求和响应是怎样运作的。 HTTP 一、HTTP报文二、请求报文及响应报文的结构三、编码提升传输速率1、报文主体和实体主题的差异2、压缩传输的内容编码3、分割发送的分块传输编…

HCIP——前期综合实验

前期综合实验 一、实验拓扑二、实验要求三、实验思路四、实验步骤1、配置接口IP地址2、交换机配置划分vlan10以及vlan203、总部分部&#xff0c;骨干网配置OSPF分部总部骨干网 4、配置BGP建立邻居关系总部骨干网分部 5、发布用户网段6、将下一跳改为本地7、允许AS重复8、重发布…

【Linux】 UDP网络套接字编程

&#x1f34e;作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;Linux系统网络编程 文章目录 一、网络通信的本质&#xff08;port标识的进程间通信&#xff09;二、传输层协议UDP/TCP认识传输层协议UDP/TCP网络字节序问题&#xff08;规定大端&#xff09; 三、socket编…

前端面试题-react

1 React 中 keys 的作⽤是什么&#xff1f; Keys 是 React ⽤于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识在开发过程中&#xff0c;我们需要保证某个元素的 key 在其同级元素中具有唯⼀性。在 React Diff 算法中 React 会借助元素的 Key 值来判断该元素是新近创建…

第十三章 利用PCA简化数据

文章目录 第十三章 利用PCA简化数据13.1降维技术13.2PCA13.2.1移动坐标轴 13.2.2在NumPy中实现PCA13.3利用PCA对半导体制造数据降维 第十三章 利用PCA简化数据 PCA&#xff08;Principal Component Analysis&#xff0c;主成分分析&#xff09;是一种常用的降维技术&#xff0…

剑指offer41.数据流中的中位数

我一开始的想法是既然要找中位数&#xff0c;那肯定要排序&#xff0c;而且这个数据结构肯定要能动态的添加数据的&#xff0c;肯定不能用数组&#xff0c;于是我想到了用优先队列&#xff0c;它自己会排序都不用我写&#xff0c;所以addNum方法直接调用就可以&#xff0c;但是…

MAC电脑设置charles,连接手机的步骤说明(个人实际操作)

目录 一、charles web端设置 1. 安装charles之后&#xff0c;先安装证书 2. 设置 Proxy-Proxy Settings 3. 设置 SSL Proxying 二、手机的设置 1. 安卓 2. ios 资料获取方法 一、charles web端设置 1. 安装charles之后&#xff0c;先安装证书 Help-SSL Proxying-Inst…

sql group by 加条件

在SQL中&#xff0c;可以在GROUP BY子句中加入条件&#xff0c;以进一步过滤结果。你可以使用HAVING子句来添加条件。HAVING子句的使用方式类似于WHERE子句&#xff0c;但不同的是&#xff0c;它用于对GROUP BY子句生成的分组进行过滤。 以下是一个示例&#xff0c;演示如何在…

优化基于tcp,socket的ftp文件传输程序

原始程序&#xff1a; template_ftp_server_old.py&#xff1a; import socket import json import struct import os import time import pymysql.cursorssoc socket.socket(socket.AF_INET, socket.SOCK_STREAM) HOST 192.168.31.111 PORT 4101 soc.bind((HOST,PORT)) p…