深入理解ConcurrentHashMap源码解析

ConcurrentHashMap是Java中一个非常重要的并发集合类,它提供了线程安全的哈希表实现。其初衷是为了优化同步HashMap,减少线程竞争,提高并发访问效率。随着Java的发展,ConcurrentHashMap在1.7和1.8中经历了显著的变化。以下内容将深入探索这两个版本的区别,同时结合源码和底层实现来进行说明。

1. Java 1.7中的ConcurrentHashMap

在Java 1.7(及之前的版本)中,ConcurrentHashMap采用了分段锁(Segmentation)的概念,其核心是将数据分成一段一段地存储,然后为每一段数据配备一把锁。

1.1 核心实现

在Java 1.7中,ConcurrentHashMap内部维护了一个Segment数组。每个Segment继承自ReentrantLock并且它内部本质上是一个Hash表。这样做的好处是能够减小锁的粒度,提高并发访问的效率。默认Segment 数量为 16,可以通过构造函数来修改默认值。当需要put或get一个元素时,线程首先通过hash定位到具体的Segment,然后在对应的Segment上进行锁定操作。

static final class Segment<K,V> extends ReentrantLock implements Serializable {// 省略其他属性和方法// Segment内部的HashEntry数组transient volatile HashEntry<K,V>[] table;Segment(float loadFactor, int threshold, HashEntry<K,V>[] tab) {this.loadFactor = loadFactor;this.threshold = threshold;this.table = tab;}// 其他方法...
}

1.2 写操作

当进行写操作时,需要首先定位到具体的Segment,然后对其加锁,执行操作后再解锁。这意味着同时只有一个线程可以在一个Segment内进行写操作,但是多个线程可以并发对不同的Segment进行操作。

public V put(K key, V value) {if (value == null)throw new NullPointerException();int hash = hash(key);int i = (hash >>> segmentShift) & segmentMask;return segments[i].put(key, hash, value, false);
}

1.3 读操作

对于读操作,如果没有进行结构修改,可以允许一定程度的并发。如果读操作需要确保最新的数据被读取,可能需要对Segment进行加锁。

2. Java 1.8中的ConcurrentHashMap

Java 8中对ConcurrentHashMap的实现进行了重大的改进。在这个版本中,去掉了Segment的概念,转而使用了CAS操作(Compare-And-Swap)和synchronized关键字配合节点的锁实现高效的并发控制。

2.1 核心实现

在Java 1.8中,ConcurrentHashMap内部主要是由Node数组构成,每个Node包含了一个key-value键值对。

static class Node<K,V> implements Map.Entry<K,V> {final int hash;final K key;volatile V value;volatile Node<K,V> next;Node(int hash, K key, V value, Node<K,V> next) {this.hash = hash;this.key = key;this.value = value;this.next = next;}// 其他方法...
}

2.2 写操作

写入时,如果目标位置为空(指的是 hash值 或数组上面的链表),将使用CAS操作进行写入。如果已经有节点存在,那么就使用synchronized锁定头节点,然后在链表上进行操作,如果是红黑树则在树上进行操作。

final V putVal(K key, V value, boolean onlyIfAbsent) {if (key == null || value == null) throw new NullPointerException();int hash = spread(key.hashCode());int binCount = 0;for (Node<K,V>[] tab = table;;) {Node<K,V> f; int n, i, fh; K fk; V fv;// ...if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {if (casTabAt(tab, i, null,new Node<K,V>(hash, key, value, null)))break;                   // no lock when adding to empty bin}// ...}return null;
}

2.3 读操作

Java 8的ConcurrentHashMap在读操作上基本不加锁(除非在读操作过程中检测到写操作正在进行),利用volatile关键字的读写内存语义来保证可见性,从而大大提高读操作的并发性。

public V get(Object key) {Node<K,V>[] tab; Node<K,V> e, p; int n, eh; K ek;int h = spread(key.hashCode());if ((tab = table) != null && (n = tab.length) > 0 &&(e = tabAt(tab, (n - 1) & h)) != null) {if ((eh = e.hash) == h) {if ((ek = e.key) == key || (ek != null && key.equals(ek)))return e.val;}// ...}return null;
}

3. 结构优化

自Java 1.8开始,ConcurrentHashMap内部结构由链表逐渐转化为红黑树,以减少搜索时间。链表在元素数量增加到一定程度时会转换为红黑树结构。

4. 总结

Java 1.7的ConcurrentHashMap通过分段锁实现高并发,但它的并发度受限于Segment的数量。而Java 1.8通过精细化控制,只在必需时进行锁定,显著提升了读写性能,尤其是读操作几乎不受影响,这对于读多写少的场景来说是一个巨大的优化。

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

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

相关文章

基于ssm vue技术的品牌银饰售卖平台源码和论文737

摘 要 本论文主要是针对品牌银饰售卖而开发进行概述&#xff0c;主要包括对研究的背景和研究现状&#xff0c;以及研究目的等的阐述&#xff0c;也对该系统的各种功能要求&#xff0c;对系统结构&#xff0c;数据库的设计等进行讨论。随着科技与技术的发展&#xff0c;利用计…

Qt篇——QChartView实现鼠标滚轮缩放、鼠标拖拽平移、鼠标双击重置缩放平移、曲线点击显示坐标

话不多说。 第一步&#xff1a;自定义QChartView&#xff0c;直接搬 FirtCurveChartView.h #ifndef FITCURVECHARTVIEW_H #define FITCURVECHARTVIEW_H #include <QtCharts>class FitCurveChartView : public QChartView {Q_OBJECTpublic:FitCurveChartView(QWidget *…

MySQL 8.x 自签证书通过keytool和openssl转成JKS文件

一、写在前面 数据库MySQL 8.0 通过自签命令在datadir下生成了所有的证书文件。由于Java的JDK不支持直接加载PEM格式的证书&#xff0c;所以需要将PEM格式证书转换成Java能够直接加载的JKS格式证书。我们需要将根证书ca.pem转换成JKS格式的根证书truststore.jks&#xff0c;将…

把 Windows 11 装进移动硬盘:Windows 11 To Go

本篇文章聊聊如何制作一个可以“说带走就带走”的 Windows 操作系统&#xff0c;将 Windows11 做成能够放在 U 盘或者移动硬盘里的 WinToGo “绿色软件”。 写在前面 在《开源的全能维护 U 盘工具&#xff1a;Ventoy》这篇文章的最后&#xff0c;我提到了一个关键词 “WinToG…

html之JS

1、JS的引入 <!-- 内嵌 --><!-- <script>alert(4)</script> --><!-- 外引 --><!-- 内嵌和外引同时有的时候&#xff0c;内嵌被覆盖 --><script src"js/index.js" defer></script>//defer 延迟执行 2、js的变量使用…

基于IText7 PDF模板填充?

引入依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itext7-core</artifactId><version>8.0.1</version><type>pom</type> </dependency> <dependency><groupId>com.itextpdf</gr…

Mybatis XML 配置文件

我们刚开始就有说Mybatis 的开发有两种方式: 1.注释 2.XML 注解和 XML 的方式是可以共存的 我们前面说的都是注释的方式,接下来是XML方式 XML的方式分为三步 : 1.配置数据库(配在 application.yml 里面) 这个跟注释的配置是一样的,username应该都是一样的,password记得写…

1. 小游戏(贪心)

题干&#xff1a; 谷同学很喜欢玩计算机游戏&#xff0c;特别是战略游戏&#xff0c;但是有时他不能尽快找到解所以常常感到很沮丧。现在面临如下问题&#xff1a;他必须在一个中世纪的城堡里设防&#xff0c;城堡里的道路形成一棵无向树。要在结点上安排最少的士兵使得他们可以…

MySql配置主从服务器复制数据库数据

主从服务器MySql版本尽可能一致。如果不一致的情况此文没考虑。 主服务器必须开启二进制日志文件。查看是否开启&#xff1a; SHOW VARIABLES LIKE log_bin; 开启方法&#xff0c;只需要在配置文件添加如下配置&#xff1a; [mysqld] log-binmysql-bin 1、MySql主服务器…

6.Eclipse里下载Subclipse插件

方法一&#xff1a;从Eclipse Marketplace里面下载 具体操作&#xff1a;打开Eclipse --> Help --> Eclipse Marketplace --> 在Find中输入subclipse搜索 --> 找到subclipse点击install 方法二&#xff1a;从Install New Software里下载 具体操作&#xff1a;打开…

高压电网过电压在线监测系统的研究

摘要 由于高压输电线路纵横延伸几十甚至几百千米&#xff0c;处在不同的环境中。因此高压输电线路受所处地理环境和气候影响很大&#xff0c;每年电网停电事故主要由线路事故引起。传统输电线路检查主要依靠运行维护人员周期性巡视&#xff0c;虽能发现设备隐患&#xff0c;但…

Qt与Sqlite3

操作流程&#xff1a; (1)与数据库连接 (2)进行增删改查操作 (3)关闭数据库 示例&#xff1a; 参考&#xff1a;Qt 操作SQLite数据库_qt sqlite数据库操作_houxian1103的博客-CSDN博客 再谈QSqlQuery::exec: database not open问题的解决_qt database not open-CSDN博客…

JavaScript中的递归函数

再此之前呢&#xff0c;我们要先知道什么是递归函数&#xff1f; 一.什么是递归函数&#xff1f; 递归函数&#xff1a;是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法&#xff0c;也是一种循环运算的一种算法模式。这种技术可以用来解决一些复杂的问题&…

OSPF浅析

一、预习&#xff1a; 1、优点&#xff1a; 是一种典型的链路状态路由协议&#xff0c;协议号89&#xff0c;把大型网络分隔为多个较小、可管理的单元&#xff1a;Area a.减少LSA泛洪范围&#xff0c;有效地把拓朴变化 控制在区域内&#xff0c;达到网络优化的目的…

nodejs微信小程序+python+PHP本科生优秀作业交流网站的设计与实现-计算机毕业设计推荐

通过软件的需求分析已经获得了系统的基本功能需求&#xff0c;根据需求&#xff0c;将本科生优秀作业交流网站功能模块主要分为管理员模块。管理员添加系统首页、个人中心、用户管理、作业分类管理、作业分享管理、论坛交流、投诉举报、系统管理等操作。 随着信息化社会的形成…

【面试HOT200】二叉树的构建二叉搜索树篇

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招面试的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于【CodeTopHot200】进行的&#xff0c;每个知识点的修正和深入主要参…

Leetcode 77 组合

题意理解&#xff1a; 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 如&#xff1a;n3,k2,则有&#xff1a;12 13 23 一般&#xff0c;我们使用回溯法来解决组合问题。 组合问题没有顺序要求&#xff0c;所以 12 21 是同一个组合&#xff08;如…

【Linux知识点汇总】01 Linux常见版本

常见的Linux发行版&#xff08;Distribution&#xff0c;简称为distro&#xff09;有很多&#xff0c;它们在用途、包管理系统、默认桌面环境等方面可能有所不同 CentOS 特点&#xff1a; 企业级稳定性&#xff0c;是Red Hat Enterprise Linux&#xff08;RHEL&#xff09;的开…

黑苹果配置清单

手里的MacBookPro已经快沦为电子垃圾了&#xff0c;平时用MacOS比较多&#xff0c;Window用的比较少&#xff0c;而苹果电脑的价格不管是MacBookPro还是MacMini丐版的便宜但是面对现在Window动不动就64g内存的情况就显得微不足道了&#xff0c;高配的价格直接把我劝退&#xff…

PostgreSql HOT 技术

摘自唐成的《PostgreSQL修炼之道&#xff1a;从小工到专家&#xff08;第2版&#xff09;》。 一、概述 因为多版本的原因&#xff0c;当 PostgreSQL 中更新一行时&#xff0c;实际上原数据行并不会被删除&#xff0c;只是插入了一个新行。如果表上有索引&#xff0c;而更新的…