Java并发编程之ConcurrentHashMap的原理和使用

ConcurrentHashMap(CHM)是Java为解决高并发场景下哈希表性能瓶颈而设计的线程安全容器,其核心目标在于:

  • 线程安全‌:避免多线程操作导致的数据不一致问题‌;
  • 高吞吐量‌:通过细粒度锁和无锁化设计降低线程竞争‌;
  • 动态扩展‌:支持自动扩容与数据结构优化(如链表转红黑树)‌;

下面我们一起详细看看ConcurrentHashMap的细节是什么样的

一、ConcurrentHashMap 概述

‌ConcurrentHashMap(CHM)‌ 是 Java 并发包中实现线程安全的哈希表,其核心设计目标是‌在高并发场景下兼顾性能与线程安全‌。与 HashTable 的全表锁不同,CHM 通过‌分段锁(JDK7)‌和‌CAS+synchronized细粒度锁(JDK8+)‌ 实现高效并发控制,解决了传统同步容器的性能瓶颈‌。

二、核心工作原理

2.1 数据结构的演进

1)JDK7 分段锁机制‌

  • 采用 ‌Segment 数组 + HashEntry 链表‌ 的二级结构,每个 Segment 继承 ReentrantLock,独立管理一个子哈希表。‌
  • 锁粒度‌:以 Segment 为锁单位,不同 Segment 的写操作可并行‌。‌
  • 缺点‌:Segment 数量固定(默认16),扩容仅针对单个 Segment,无法全局动态调整‌。

2)‌JDK8+ 优化设计‌

  • Node 数组 + 链表/红黑树‌:取消 Segment,直接使用 Node 数组,链表长度超过8时转为红黑树(避免哈希冲突导致的性能退化)‌。
  • 锁粒度细化‌:仅对单个桶(Node 数组元素)加锁(通过 synchronized 和 CAS),并发度更高‌。

具体版本对比如下
在这里插入图片描述

2.2 线程安全机制

1)CAS(Compare And Swap)‌:用于无锁化更新头节点、统计元素数量(如 sizeCtl)等场景,减少线程阻塞‌。
2‌)Synchronized 锁‌:针对具体桶(Node)加锁,仅当哈希冲突时触发,避免全局锁竞争‌。
‌3)Volatile 变量‌:保证内存可见性,如 Node.val 和 next 指针均用 volatile 修饰‌。

2.3 JDK8实现原理和源码解析

1)核心数据结构

// Node节点定义(链表结构)  
static class Node<K,V> implements Map.Entry<K,V> {  final int hash;  final K key;  volatile V val;          // 保证可见性  volatile Node<K,V> next; // 保证可见性  // ...  
}  // TreeNode节点(红黑树结构)  
static final class TreeNode<K,V> extends Node<K,V> {  TreeNode<K,V> parent;  TreeNode<K,V> left;  TreeNode<K,V> right;  TreeNode<K,V> prev;  boolean red;  
}  

设计要点‌:

  1. volatile修饰‌:val和next字段确保内存可见性‌;
  2. 树化

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

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

相关文章

AbMole揭秘伤口愈合:IGF-1-SP1-CD248信号通路的新发现

科学家们揭示了一条新的信号通路——IGF-1-SP1-CD248&#xff0c;这一发现为理解伤口愈合障碍提供了新的视角&#xff0c;并为未来的研究开辟了新方向。 研究背景 糖尿病患者的伤口愈合是一个长期存在的挑战。据统计&#xff0c;约15%的糖尿病患者会遭受慢性伤口的困扰&#…

Go入门之文件

以只读方式打开文件 package mainimport ("fmt""io""os" )func main() {file, err : os.Open("./main.go")defer file.Close()if err ! nil {fmt.Println(err)return}fmt.Println(file)var tempSlice make([]byte, 128)var strSlice…

python量化交易——金融数据管理最佳实践——使用qteasy管理本地数据源

文章目录 统一定义的金融历史数据表最重要的数据表数据表的定义交易日历表的定义&#xff1a;交易日历表: trade_calendar qteasy是一个功能全面且易用的量化交易策略框架&#xff0c; Github地址在这里。使用它&#xff0c;能轻松地获取历史数据&#xff0c;创建交易策略并完…

通过 PromptTemplate 生成干净的 SQL 查询语句并执行SQL查询语句

问题描述 在使用 LangChain 和 Llama 模型生成 SQL 查询时&#xff0c;遇到了 sqlite3.OperationalError 错误。错误信息如下&#xff1a; OperationalError: (sqlite3.OperationalError) near "sql SELECT Name FROM MediaType LIMIT 5; ": syntax error [SQL: …

STaR(Self-Taught Reasoner)方法:让语言模型自学推理能力(代码实现)

STaR&#xff08;Self-Taught Reasoner&#xff09;方法&#xff1a;让语言模型自学推理能力 在大型语言模型&#xff08;LLM&#xff09;的推理能力优化中&#xff0c;STaR&#xff08;Self-Taught Reasoner&#xff09; 是一种引人注目的技术&#xff0c;属于“修改提议分布…

Asp.Net Web API| React.js| EF框架 | SQLite|

asp.net web api EF SQLiteReact前端框架 设计一个首页面&#xff0c;包含三个按钮分别对应三类用户&#xff08;数据查看&#xff0c;设计人员&#xff0c;管理员&#xff09;&#xff0c;当点击管理员的时候弹出一个前端页面可以输入信息&#xff08;以学生数据为例&#…

[SWPUCTF 2022 新生赛]1z_unserialize

题目描述&#xff1a;是很简单的反序列化噢 代码审计看注释 <?phpclass lyh{ //定义一个类为lyhpublic $url NSSCTF.com;//公共属性&#xff0c;初始值为NSSCTF.compublic $lt; //公共属性&#xff0c;没有初始值public $lly; //公共属性&…

【数据库】Update两阶段提交

为什么要两阶段提交 事务提交之后&#xff0c;redo log和bin log 都是需要1持久化到磁盘中&#xff0c;但是这两个是独立的逻辑&#xff0c;可能出现半成功的状态&#xff0c;这样就造成两份日志之间的逻辑不一致。如&#xff1a; 以id1&#xff0c;name ‘小明’执行 updat…

【蓝桥】排序

1、sort简介 sort函数包含在头文件<algorithm>中sort函数使用之前&#xff0c;需要通过#include <algorithm>引入sort函数使用的是快速排列或类似快速排列的改进算法&#xff0c;时间复杂度一般为O(nlog(n)) 2、sort用法 2.1 基础用法 #include <iostream>…

2024年中国城市统计年鉴(PDF+excel)

2024年中国城市统计年鉴&#xff08;PDFexcel&#xff09; 说明&#xff1a;包括地级县级市 格式&#xff1a;PDFEXCEL 《中国城市统计年鉴》是一部全面反映中国城市发展状况的官方统计出版物&#xff0c;包括各级城市的详细统计数据。这部年鉴自1985年开始出版&#xff0c;…

android 资源selector写法注意

1、res文件夹下面color文件夹,放的xml <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/color_brand1" android:s…

蓝桥杯 灯笼大乱斗【算法赛】

问题描述 元宵佳节&#xff0c;一场别开生面的灯笼大赛热闹非凡。NN 位技艺精湛的灯笼师依次落座&#xff0c;每位师傅都有相应的资历值&#xff0c;其中第 ii 位师傅的资历值为 AiAi​。从左到右&#xff0c;师傅们的资历值逐级递增&#xff08;即 A1<A2<⋯<ANA1​&l…

商城源码的框架

商城源码的框架通常是基于某种Web开发框架或者电子商务平台来构建的。以下是一些常见的商城源码框架&#xff1a; WooCommerce&#xff1a;基于WordPress的电子商务插件&#xff0c;适用于小型到中型的在线商店。 Magento&#xff1a;一个功能强大和灵活的开源电子商务平台&am…

HarmonyOS 5.0应用开发——多线程Worker和@Sendable的使用方法

【高心星出品】 文章目录 多线程Worker和Sendable的使用方法开发步骤运行结果 多线程Worker和Sendable的使用方法 Worker在HarmonyOS中提供了一种多线程的实现方式&#xff0c;它允许开发者在后台线程中执行长耗时任务&#xff0c;从而避免阻塞主线程并提高应用的响应性。 S…

避坑!用Docker搞定PHP开发环境搭建(Mac、Docker、Nginx、PHP-FPM、XDebug、PHPStorm、VSCode)

本次更新主要是对环境版本进行了更新&#xff0c;例如php 7.3.7升级到了7.3.8&#xff0c;另外之前的版本有同学踩了坑&#xff0c;主要是官方docker镜像php:7.3.7-fpm和php:7.3.8-fpm使用了不同版本的debian&#xff0c;后面会提到&#xff0c;请各位同学留意。 因为最近换电脑…

自动化测试开发

4、Servlet模型&#xff08;一&#xff09; Servlet的编写、访问过程 Servlet简介 Servlet是Java Servlet的简称&#xff0c;是小服务程序或服务连接器&#xff0c;是用Java编写的服务器端程序&#xff0c;主要功能在于获取请求&#xff0c;返回响应广义&#xff1a;一个Ser…

24、Java 集合

十一章&#xff1a;Java 集合 一、集合框架的概述 1、集合&#xff1a;就像一个容器&#xff0c;可以动态的把多个对象的引用放入容器中。简称 Java 容器 ​ 说明&#xff1a;此时的存储&#xff0c;主要指的是内存层面的存储&#xff0c;不涉及到持续化的存储&#xff08;.t…

1114棋盘问题acwing(深度优先搜索)

题目描述 在一个给定形状的棋盘&#xff08;形状可能是不规则的&#xff09;上面摆放棋子&#xff0c;棋子没有区别。 要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列&#xff0c;请编程求解对于给定形状和大小的棋盘&#xff0c;摆放 kk 个棋子的所有可行的摆放…

logback日志输出配置范例

logback日志输出配置范例 在wutool中&#xff0c;提供了logback日志输出配置范例&#xff0c;实现日志文件大小限制、滚动覆盖策略、定时清理等功能。 关于wutool wutool是一个java代码片段收集库&#xff0c;针对特定场景提供轻量解决方案&#xff0c;只要按需选择代码片段…

测试人员如何驱动开发?

软件开发中测试人员的作用正在从传统的缺陷发现者演变为开发过程的主动推动者。特别是在敏捷和 DevSecOps 环境中&#xff0c;测试人员如何通过参与需求、提供反馈和推动自动化来驱动开发&#xff0c;成为一个值得探讨的话题。本文将详细分析测试人员驱动开发的具体方式&#x…