java8中为什么放弃了ConcurrentMap的分段锁,采取了什么新的策略

13 ConcurrentMap & Copy-On-Write容器 1.1 ConcurrentMapConcurrentMap接口有两个实现类:ConcurrentHashMapConcurrentSkipListMap(支持排序功能,弥补ConcurrentHashMap)ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的HashTable,他们有自己锁。只要多个修改操作发生在不同的段上,他们就可以并发进... 阅读详情

java8中为什么放弃了ConcurrentMap的分段锁,采取了什么新的策略

前言

ConcurrentMap,它是一个接口,是一个能够支持并发访问的java.util.map集合;

ConcurrentHashMap是一个线程安全,并且是一个高效的HashMap。

spring 缓存注解 通过查看源代码发现将数据存在ConcurrentMap中

它的原理是引用了内部的 Segment ( ReentrantLock ) 分段锁,和hashmap一样,在jdk1.7中ConcurrentHashMap的底层数据结构是数组加链表。和hashmap不同的是ConcurrentHashMap中存放的数据是一段段的,即由多个Segment(段)组成的。每个Segment中都有着类似于数组加链表的结构。

保证在操作不同段 map 的时候, 可以并发执行, 操作同段 map 的时候,进行锁的竞争和等待。从而达到线程安全, 且效率大于 synchronized。

但是在 Java 8 之后, JDK 却弃用了这个策略,重新使用了 synchronized+cas。

弃用原因

通过 JDK 的源码和官方文档看来, 他们认为的弃用分段锁的原因由以下几点:

  1. 加入多个分段锁浪费内存空间。
  2. 生产环境中, map 在放入时竞争同一个锁的概率非常小,分段锁反而会造成更新等操作的长时间等待。
  3. 为了提高 GC 的效率

什么是可重入锁(递归锁)

定义:当某个线程已经获得某个锁,可以再次获取锁而不会发生死锁,可以多次获取相同的锁。
优点:可以再一定程度上避免死锁。

新的方案

既然弃用了分段锁, 那么一定由新的线程安全方案, 我们来看看源码是怎么解决线程安全的呢?(源码保留了segment 代码, 但并没有使用)

put
首先通过 hash 找到对应链表过后, 查看是否是第一个object, 如果是, 直接用cas原则插入,无需加锁。
然后, 如果不是链表第一个object, 则直接用链表第一个object加锁,这里加的锁是synchronized,虽然效率不如 ReentrantLock, 但节约了空间,这里会一直用第一个object为锁, 直到重新计算map大小, 比如扩容或者操作了第一个object为止。

为什么是synchronized,而不是ReentranLock

  1. 减少内存开销
    假设使用可重入锁来获得同步支持,那么每个节点都需要通过继承AQS来获得同步支持。但并不是每个节点都需要获得同步支持的,只有链表的头节点(红黑树的根节点)需要同步,这无疑带来了巨大内存浪费。
  2. 获得JVM的支持
    可重入锁毕竟是API这个级别的,后续的性能优化空间很小。
    synchronized则是JVM直接支持的,JVM能够在运行时作出相应的优化措施:锁粗化、锁消除、锁自旋等等。这就使得synchronized能够随着JDK版本的升级而不改动代码的前提下获得性能上的提升。
Java容器之ConcurrentHashMap源码分析(JDK 1.7与JDK 1.8对比)   在前面两篇博客 Java容器之HashMap源码分析、Java容器之Hashtable源码分析分别对JDK1.8中的HashMap、Hashtable的源码进行一些分析,在本篇博客将对ConcurrentHashMap容器的源码进行一些分析。 申明:在前两篇博客介绍了两个容器的增、删、改、查相关的API,并且给源码加上了中文注释,在本篇博客将只介绍一些关键的API,比如hash值的计算,put... 阅读详情

相关推荐

PotPlayer 史诗级更新!实时字幕生成+实时翻译,看片真的无敌了!

potplayer已经更新实时字幕生成+实时字幕翻译功能

阿虚同学的博客 1万+

ConcurrentHashMap(JDK1.8)为什么要放弃Segment

今天看到一篇博客:jdk1.8的HashMap和ConcurrentHashMap,我想起了前段时间面试的一个问题:ConcurrentHashMap(JDK1.8)为什么要使用synchronized而不是可重入锁?我想从下面几个角度讨论这个问题: 锁的粒度 首先锁的粒度并没有变粗,甚至变得更细了。每当扩容一次,ConcurrentHashMap的并发度就扩大一倍。 Hash冲突 JDK1.7

乐天派 2万+

手把手教你用STM32CubeMX配置I3C通信(含动态地址分配实战)

本文提供了一份基于STM32CubeMX配置I3C通信的实战指南,重点讲解了动态地址分配的实现步骤。通过详细的工程配置、从设备枚举、CCC命令使用及数据读写示例,帮助开发者快速掌握这一高效通信协议,以替代传统的I2C或SPI接口,满足多传感器连接与低功耗设计需求。

c8d9e0f1的博客 542

从ConcurrentHashMap出发引发的一系列思考

在做mit6.830时,关于数据库的全局目录catalog类持有一个线程安全的去保存数据库中每一张表。为了避免多个线程对数据库目录修改造成数据不一致的情况,是不能使用HashMap的,这是因为HashMap是线程不安全的。...

weixin_44153131的博客 1259

Blazor Session设置

微软官方封装了一些浏览器的操作,其中就有Session的操作的封装ProtectedSessionStorage 微软文档因为我们知道,依赖注入的生命周期是Singleton程序Scoped网页:刷新,url直接跳转都会重置。Transient路由C# Blazor 学习笔记(10):依赖注入但是没有一个和浏览器绑定的生命周期。即浏览器关闭才会退出。这个是后端无法获取的,因为后端根本不知道浏览器何时关闭。这个只能用浏览器自带的缓存。

qq_44695769的博客 1786

RK3588 Linux启动优化至亚秒级全链路剖析

本文深入探讨RK3588平台Linux系统启动加速技术,涵盖从BL1/ATF安全固件、U-Boot剪裁到内核精简化等全链路优化方案,实现从上电到用户脚本800ms内完成的实战经验。​​文末提供完整解决方案获取方式​​。由于在 ARMv6 之后引入了 TrustZone 模块, 目前市面上 ARMv7 和 ARMv8 之后的系统都会包含了该模块, 这个模块由 BL1 启动, 且在 ATF(ARM Trust Firmware) 固件中, 既安全世界中引导到 BL33 (UBOOT)的系统。

韩若明溪 1777

放弃分段锁,Java 8的ConcurrentHashMap为何更具性能优势

在多核处理器的背景下,Java 8中的ConcurrentHashMap采用了全新的实现方式,放弃了分段锁的机制,而采用了CAS和synchronized的组合方式来保证并发安全。这种实现方式具有更高的并发性能、更少的复杂性和更好的可伸缩性,因此成为了Java中并发编程的重要组件之一。同时,由于Java 8中的ConcurrentHashMap在内部实现上采用了数组+链表+红黑树的数据结构,也使得其具有较好的查找和遍历性能,可以适用于各种场景。

CXikun的博客 320

[华为ensp]双核心的园区网

(给部分只会emm......借鉴的朋友提个醒,在group-member e0/0/2 to e0/0/20是所选,所以到了p l t那会给2-20端口都配置上trunk,别紧张,不是你问题)完成上述配置后,PC1可以ping通HTTP2服务器,Client1可以访问HTTP2服务器的HTTP站点,如果不能就要检查上述是否正确。本次实验主要目的是采用双核心的冗余网络,采用MSTP和VRRP技术,在核心层交换机上配置SC1上配置OSPF协议。SC1交换机上配置VRRP。在SC1上配置DHCP。

2301_78859499的博客 1416

面试官:ConcurrentHashMap为什么放弃了分段锁?

今天我们来讨论一下一个比较经典的面试题就是 ConcurrentHashMap 为什么放弃使用了分段锁,这个面试题阿粉相信很多人肯定觉得有点头疼,因为很少有人在开发中去研究这块的内容,今天...

磊哥聊Java 5292

最新 抖音 X-Gorgon 0408 和8408 设备注册协议

抖音app先是检测了你的手机cpu架构,是x86还是armeabi,通过cpu架构的不同来调用so内不同的xg方法,所以导致现在最新版抖音app的xg算法有0408和8408两种。两种都是最新版,因为我发现当我使用oppo手机安装最新版抖音抓包的xg是8408,而当我用小米或者华为安装最新版抖音,抓包以后发现xg是0408。抖音IOS XG84 设备注册激活协议代码片段。...

Q44804487的博客 1万+

实测可复现|2026 Cloudflare盾v4.0反反爬全实战:从JS/WASM逆向到JA3指纹伪装,手把手突破拦截(附完整逆向代码+避坑手册)

本文以2026年Cloudflare盾v4.0(集成Shield Synapse v2.0)为核心,全程以实战复盘为视角,拆解了从JS/WASM混合逆向、全维度指纹伪装(JA3+浏览器指纹)、人类行为模拟,到代理池搭建的全流程,整合了完整可复现的代码,所有步骤和踩坑点均为实测所得,无任何AI套话,新手也能跟着复现,最终实现爬取成功率从12%提升至95%+。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1686

JAVA8的ConcurrentHashMap为什么放弃了分段锁,有什么问题吗,如果你来设计,你如何 设计。

jdk8 放弃了分段锁而是用了Node锁,减低锁的粒度,提高性能,并使用CAS操作来确保Node的一些操作的原子性,取代了锁。 但是ConcurrentHashMap的一些操作使用了synchronized锁,而不是ReentrantLock,虽然说jdk8的synchronized的性能进行了优化,但是我觉得还是使用ReentrantLock锁能更多的提高性能 ...

qq_43295866的博客 1万+

【毕设实战】飞行器目标识别系统:基于YOLOv5的智能检测全流程教程,助你毕设脱颖而出

亲爱的同学,毕设是不是让你既期待创新又担心技术门槛?如果你的毕设方向是计算机视觉、智能检测,那这个绝对能成为你的“毕设王牌”。从数据准备到界面开发,我会把整个项目拆成“傻瓜式”步骤,让你能一步步做出属于自己的毕设成果。

know_F0727的博客 104

(十)Java-ConcurrentMap

ConcurrentMap 是 Java 中 java.util.concurrent 包的一部分,是 Map 接口的一个子接口。它提供了线程安全的 Map 实现,适用于多线程环境下进行并发读写时的高效操作。

qq_50847694的博客 1401

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

并发容器之ConcurrentMap

哈希函数根据hashCode计算出哈希值,这里的hash值与HashMap的计算方式稍微有点不同,在低十六位异或高十六位之后还需要与HASH_BITS在进行与运算,HASH_BITS的值是0x7fffffff,转为二进制是31个1,进行与运算是为了保证得到的hash值为正数。CAS包含三个操作数,---内存中的值(V),预期原值(A),新值(B) 如果内存中的值和A的值一样,就可以将内存中的值更新为B。CAS是compare and swap的缩写,即我们所说的比较交换,CAS属于乐观锁。

Lxn2zh的博客 906

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

ConcurrentMap原理详解

ConcurrentMap原理详解 jdk1.8 数据结构 数组+链表+红黑树 Node<K,V>{} static class Node<K,V> implements Entry<K,V> { final int hash; final K key; volatile V val; volatile Node<K,V> next; 如何线程安全 数组桶值设置和更新使用CAS算法 tabAt(Node<K,V>[] tab, i

mrb1289798400的博客 1002

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Java 入门指南:Java 并发编程 —— 并发容器 ConcurrentHashMap

ConcurrentHashMap 是线程安全的,支持完全并发的读取,并且有很多线程可以同时执行写入。在早期版本(例如 JDK 1.7)中,ConcurrentHashMap 使用分段锁技术。整个哈希表被分成一些段(Segment),每个段独立加锁。这样,在不同段上的操作可以并发进行。 从 JDK 1.8 开始,ConcurrentHashMap 的内部实现有了很大的变化。它放弃了分段锁技术,转而采用了更先进的并发控制策略,如 CAS 操作和红黑树等,进一步提高了并发性能。

热带鱼的技术博客 1845

解析ConcurrentHashMap:分段锁到synchronized+红黑树

本文深入解析了JDK8中ConcurrentHashMap的重大改进,重点对比了与JDK7版本的关键差异。JDK8摒弃了分段锁设计,采用更细粒度的synchronized+红黑树结构,通过桶级别锁、CAS操作和多线程协作扩容等创新机制,显著提升了并发性能和内存效率。文章详细剖析了put/get操作原理、红黑树转换条件及扩容机制,并提供了性能对比和使用建议。这些改进使ConcurrentHashMap更好地适应现代多核处理器架构,成为高并发场景下的优选容器。

源码获取 | 运行部署 | 定制二开修改,如果回复不及时请耐心等待,请见谅。 1206

高并发基础——JUC(concurrentMap,executorService)

一.ConcurrentMap(并发映射): 引入: 之前在Java基础中,我们学习过了map和它的子类hashmap,hashtable。所以在学习concurrentMap之前我们需要复习一下,hashmap的原理。 hashmap原理: 底层是使用 数组+链表 ,数组查询快,链表增删快。所以hashmap查询快增删也快。默认初始容量是16,默认加载因子0.75 hashmap中我们知道,它是线程不安全的,通俗的说,就是一个线程进来是没有锁来锁这个map的,这就会导致线程不安全,而今天要学习的conc

weixin_42596778的博客 510

详解ConcurrentHashMap及JDK8的优化

由于HashMap在并发中会出现一些问题,所以JDK中提供了并发容器ConcurrentHashMap。有关HashMap并发中的问题和原理,强烈建议查看这篇文章进行复习。 ConcurrentHashMap使用分段锁技术,将整个数据结构分段(默认为16段)进行存储,然后给每一段数据配一把锁(继承ReentrantLock),当一个线程占用锁访问其中一个段的数据的时候,其他段的数据仍然能被其他线...

全菜工程师小辉的博客 1万+

Java多线程进阶(十二):并发容器之ConcurrentHashMap

我们知道在java.util包下提供了一些容器类,而Vector和HashTable是线程安全的容器类,但是这些容器实现同步的方式是通过对方法加锁(sychronized)方式实现的,这样读写均需要锁操作,导致性能低下。 ConcurrentMap接口 ConcurrentMap接口继承了Map接口,在Map接口的基础上又定义了四个方法: public interface ConcurrentMa...

程铭程铭你快成名的博客 1551

从源码到性能:深入剖析Java 8种并发集合的适用场景与坑点

深入解析Java并发集合对比,揭示8种常用并发容器的适用场景与核心方法。涵盖性能差异、线程安全机制与典型坑点,帮助开发者合理选择工具提升效率。从源码到实战,值得收藏。

ByteChat的博客 857

Java HashMap、ConcurrentHashMap、SynchronizedMap、HashTable

文章目录HashMapJava7Java8ConcurrentHashMapJava7Java8SynchronizedMapHashTable HashMap Java7 Java8 Java8 对 HashMap 进行了一些修改,最大的不同就是利用了红黑树,所以其由 数组+链表+红黑树 组成。 在 Java8 中,当链表中的元素超过了 8 个以后,会将链表转换为红黑树,在这些位置进行查找的时候可以降低时间复杂度为 O(logN)。 ConcurrentHashMap Java7 整个 Concurr

jushisi的博客 279

ConcurrentMap与CopyOnWrite容器

ConcurrentMap接口下有两个重要的实现:   ConcurrentHashMap   ConcurrentSkipListMap(支持并发排序功能,弥补ConcurrentHashMap) ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的HashTable,它们有自己的锁。只要多个修改操作发生在不同的段上,他们就可以并发进行...

weixin_30537391的博客 122

如何保证线程安全有序性_ConcurrentHashMap 能否保证绝对的线程安全?

ConcurrentHashMap 是 Java 并发包中提供的一个线程安全且高效的 HashMap 实现,以弥补 HashMap 不适合在并发环境中操作使用的不足,本文就来分析下 ConcurrentHashMap 的实现原理,并对其实现原理进行分析!一、摘要在之前的集合文章中,我们了解到 HashMap 在多线程环境下操作可能会导致程序死循环的线上故障!既然在多线程环境下不能使用 H...

weixin_34119722的博客 1461

ConcurrentHashMap 原理与避坑指南:从分段锁到CAS细粒度锁

ConcurrentHashMap 是 Java 并发编程中核心的线程安全哈希表实现,其本质并非简单加锁的 HashMap,而是基于分段锁(JDK 7)演进为 CAS + synchronized 细粒度锁(JDK 8+)的高性能容器。它保证单个操作原子性与读操作完全并发,但牺牲强一致性以换取吞吐量,典型体现为弱一致性迭代器和估算型 size()。技术价值在于平衡内存、CPU 缓存行友好性与高并发写扩展性,广泛应用于缓存系统、实时风控、会话管理等场景。本文深入解析其架构跃迁、5 个关键原子 API(如 co

weixin_34326179的博客 486
上一篇: Java学习笔记:反射class.forName和ClassLoader的区别记录
下一篇: Java中String类型不可变
code_feien
博客等级 码龄7年 71粉丝 85原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值