当前位置: 首页 > news >正文

【JUC】ConcurrentHashMap全解|ReentrantLock与synchronized对比

大家好,我是程序员二叉。


简介

本篇详解ConcurrentHashMap JDK7/JDK8底层差异、放弃分段锁原因、扩容机制;对比ReentrantLock与synchronized区别,拆解ReentrantLock可重入/公平/中断/超时四大特性AQS实现原理,面试高频必背。欢迎点赞关注收藏。


一、ConcurrentHashMap JDK7 工作流程

  1. 采用Segment分段锁架构,整体由Segment数组组成,每个Segment是独立小型HashTable
  2. 存储结构:Segment[] → 内部HashEntry数组+单向链表
  3. 存取流程:
    1. key哈希取模定位对应Segment
    2. 获取Segment独占锁
    3. 二次哈希定位桶位,遍历链表增删改查
  4. 优势:相比Hashtable全局锁,多Segment可并发操作,并发能力提升

二、ConcurrentHashMap JDK8 工作流程

  1. 彻底移除Segment,顶层直接是Node数组;存储结构:数组+链表+红黑树
  2. 寻址:hash扰动计算哈希值定位桶下标
  3. 插入逻辑:
    • 桶位为空:CAS无锁直接放入Node
    • 桶位有数据:对桶头节点加synchronized
    • 链表长度≥8且数组容量≥64:链表转红黑树;元素减少退化为链表
  4. 查询全程无锁,依靠volatile保证可见性;size采用baseCount+CounterCells自旋计数

三、JDK7 与 JDK8 ConcurrentHashMap 核心区别

  1. 锁粒度
    JDK7:Segment大分段锁;JDK8:桶级细粒度synchronized+CAS
  2. 数据结构
    JDK7:数组+链表;JDK8:数组+链表/红黑树,长链表查询速度大幅提升
  3. 计数方式
    JDK7:每个Segment单独维护count;JDK8:baseCount + 分段CounterCells自旋统计
  4. 扩容模式
    JDK7:单个Segment独立扩容,互不干涉;JDK8:全局统一扩容,多线程协助迁移数据

四、JDK8 为什么废弃分段锁,改用CAS + synchronized

  1. Segment内存开销大:16个分段自带锁、计数、对象头,占用大量堆内存;桶锁轻量化无额外开销
  2. 并发吞吐量更高:同Segment下多桶无法并行,桶级锁不同哈希桶完全并发
  3. synchronized锁升级优化成熟:偏向/轻量/重量级三层升级,低竞争场景性能不输AQS锁
  4. 扩容效率提升:支持多线程一起迁移数据,分段锁只能单Segment独自扩容
  5. 代码结构简化:去掉多层嵌套Segment,逻辑简洁易维护

五、ConcurrentHashMap JDK8 扩容机制

  1. 触发阈值:元素数量达到容量 * 0.75负载因子
  2. 新table容量直接扩容为原来2倍
  3. 初始单线程创建新数组,之后其他读写线程可协助迁移旧桶数据
  4. 迁移中旧桶标记fwd占位节点,读写碰到fwd会参与协助扩容
  5. 数据迁移二分:key哈希结果只有原下标i 或 i+旧容量两个去向
  6. 全部桶迁移完毕,替换全局table引用,扩容结束

六、ReentrantLock 和 synchronized 核心区别

  1. 底层实现
    synchronized:JVM监视器Monitor,代码块结束自动释放锁;
    ReentrantLock:基于AQS的API层锁,必须手动lock()/unlock()
  2. 中断等待
    synchronized:阻塞时不可中断,只能死等;
    ReentrantLock:lockInterruptibly()支持中断抛出异常退出等待
  3. 公平锁选择
    synchronized:永久非公平锁;
    ReentrantLock:构造传true开启公平锁,默认非公平
  4. 超时等待
    synchronized:无超时机制;
    ReentrantLock:tryLock(时间,单位)超时拿锁直接返回false
  5. 多条件队列
    synchronized:只有1套wait/notify队列;
    ReentrantLock:可创建多个Condition,精准唤醒指定线程组
  6. 释放风险
    ReentrantLock必须在finally执行unlock,否则极易永久死锁;synchronized自动释放

七、ReentrantLock四大特性AQS底层实现

1. 可重入实现

AQS中state数值记录重入次数;同一线程重复获取锁state+1;释放逐层state-1,state=0才算完全释放锁。

2. 可中断实现

lockInterruptibly()阻塞park前检测中断标识;收到中断直接抛异常,清理队列节点终止等待。

3. 超时等待实现

tryLock(long, TimeUnit)自旋时记录截止时间,时间耗尽直接放弃竞争返回false。

4. 公平锁实现

公平模式acquire前先判断阻塞队列有无前驱等待节点,有则直接入队不抢先CAS;非公平模式上来直接抢锁。


面试速记总结

  1. JDK7分段锁、JDK8桶级synchronized+红黑树,细粒度锁吞吐更高
  2. JDK8多线程协作扩容,负载因子固定0.75
  3. ReentrantLock手动AQS锁,支持公平/中断/超时/Condition;synchronized是JVM自动监视器锁
http://www.zskr.cn/news/1515225.html

相关文章:

  • 60fps实时音频可视化架构:EZAudio的低延迟Core Audio实现方案
  • 2026 硬核论文降重攻略:5 款工具完美适配知网 / 维普最新模型,双率齐降一次过
  • 2026年一体化污水处理设备行业格局解析:哪些企业值得关注? - 优质品牌商家
  • 微信小程序TabBar图标包:含首页/分类/购物车/我的等多状态PNG图标(透明背景+规范命名)
  • QueryExcel:10倍效率!免费Excel批量查询工具终极指南
  • 高效语音识别实战:Omni SenseVoice 完整配置指南
  • 计算机毕业设计之书籍销售预测网站
  • MCP 终极愿景——成为 Agent 互联网的基石协议
  • 深入SIM800C:从IMEI/CCID解码到网络状态监控(AT+CSQ/AT+CREG/AT+CGATT实战解析)
  • 知网 / 维普最新算法已被破解?这几款降重工具效果逆天,赶紧收藏!
  • Windows 64位POCO 1.9.0开箱即用开发套件(含DLL/LIB/头文件及CMake集成工具)
  • KEIL5 Debug调试窗口全解析:除了变量查看,这些隐藏功能你用过吗?
  • FOFAX性能优化终极指南:大规模资产查询的并发处理策略
  • ActiveReports.NET v20.1 已发布
  • 告别VGA大块头:用FPGA驱动ST7789V小屏,做个便携显示器的保姆级教程
  • 为什么选择knausj_talon?社区驱动的Talon语音命令集优势解析
  • 如何快速安装文档下载自动化工具:新手完整指南
  • 2026年 北京货架厂家:仓储货架、重型货架、中型货架、横梁式、阁楼、悬臂、立体库货架及堆垛机系统实力供应厂家 - 品牌发掘
  • STM32串口调试救星:手把手教你用CubeMx+HAL库搞定printf重定向,告别HAL_UART_Transmit
  • EDM2图像生成教程:使用generate_images.py创建高质量视觉内容的5个技巧
  • Model Context Protocol(MCP):AI模型调用外部工具的标准化协议
  • AspectInjector未来路线图:即将到来的功能与改进计划
  • 终极指南:如何为Unity游戏选择最合适的免费去马赛克插件
  • 从波形文件瘦身到精准抓取:FSDB Dump高级选项在Verdi/nWave中的实战应用指南
  • 如何快速掌握微信聊天记录永久保存:新手完整指南
  • 2026年东莞导电塑料/防静电塑料厂家:碳纤炭黑防静电塑料源头实力品牌选购分析 - 品牌发掘
  • STM32的ADC规则通道扫盲:从‘主循环’与‘中断’的比喻,到CubeMX里‘连续’与‘非连续’模式的实战选择
  • 如何彻底解决IDM试用期限制:3种专业激活方案完全指南
  • Tree-Shaking
  • 避开这些坑!在沁恒CH582上开发USB HID设备的完整配置流程