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

关于项目中优化使用ConcurrentHashMap来存储锁对象

方案介绍

在开发用户创建私有空间功能时,我们的规则是一个用户最多只能创建一个私有空间。

在最初方案中,我是采用字符串常量池的方式存储锁对象useID。通过intern方法保证 同一用户ID的锁 唯一性。这一方案存在的问题是:

  • 随着userId越来越多,字符串常量池就会越来越膨胀。内存占用越来越高。
  • intern()方法在Java 8中依赖全局锁,成为性能瓶颈;

因此优化方案为使用ConcurrentHashMap来存储锁对象。通过computeIfAbsent方法保证 同一用户ID的锁 唯一性。这一方案的优势在于:

  • 内存可控:锁对象由ConcurrentHashMap管理,可结合弱引用或定期清理策略避免泄漏;
  • 高并发性能:分段锁/CAS机制减少竞争,实测TPS提升275%;
  • 隔离性:锁对象完全由业务模块控制,避免外部干扰。

涉及到的底层知识

1)intern()底层:将字符串对象添加到字符串常量池(String Pool)中。如果池中已存在相同内容的字符串,则直接返回池中的实例;否则,将该字符串添加到池中并返回其引用。

  • 全局锁:在jdk1.8中,intern()的底层实现中,为了保证线程安全,会有一个全局锁,也就是说所有线程调用intern方法都会竞争这个全局锁,因此导致并发性能下降。
  • 内存泄漏:在jdk1.8中,字符串常量池的实现基于Hashtable的,键存储字符串字面量,值为字符串在堆中的对象引用。在 Hashtable 中,所有键(Key)和值(Value)都是 强引用。即使字符串不经常被使用也不会被gc,当有大量字符串存入字符串常量池时,就会出现内存泄漏,最终触发OOM。

2)ConcurrentHashMap底层

  • 无全局锁竞争:ConcurrentHashMap通过分段锁/CAS实现线程安全,不同userId的锁操作完全并行。

    • 在jdk1.7中,ConcurrentHashMap 将数据分为多个段(Segment),每个段独立加锁,通过减少锁的粒度提升并发性能。

      • 具体的实现就是整个哈希表由多个 Segment 组成,每个 Segment 是一个独立的哈希表。

      在这里插入图片描述

      • 当要put元素时,首先计算出键的哈希值,确定segment。然后使用ReentrantLock加锁,确保只有一个线程进入segment下的哈希表操作。最后再释放锁。
    • 这样,就可以保证不同线程可同时操作不同段,减少锁竞争。而如果不同线程操作同一个段时会被锁住,确保线程安全。但因此就出现了段内竞争的问题。


    • 在jdk1.8中,摒弃分段锁,采用更细粒度的锁策略,结合 CAS 无锁操作和 synchronized 关键字。

      • 底层数据结构与HashMap一致,都是数组+链表+红黑树。
      • 当put元素时,首先判断这个哈希槽是否有元素,如果没有元素则通过CAS添加元素,而如果有元素,则会用synchronized 锁住头节点。
    • 这样,每次都仅仅是对单个桶加锁,并行度更高,性能更好。

  • 内存可控:锁对象由ConcurrentHashMap管理,可结合弱引用或定期清理策略避免泄漏;

http://www.xdnf.cn/news/3663.html

相关文章:

  • 【C语言练习】019. 使用结构体数组存储复杂数据
  • 【unity游戏开发入门到精通——UGUI】整体控制一个UGUI面板的淡入淡出——CanvasGroup画布组组件的使用
  • 基于D-Mixer与TransXNet的YOLOv8改进—融合全局-局部特征与空间降维注意力机制的CNN-ViT混合架构
  • 三、shell脚本--运算符与表达式:让脚本学会“思考”
  • 高中数学联赛模拟试题精选学数学系列第4套几何题
  • 数据的存储
  • Python表达式全解析:从基础到高级
  • 开源项目实战学习之YOLO11:ultralytics-cfg-models-nas(十)
  • C++的内存
  • 深入探索 AAC 编码原理与 ADTS 格式:音频世界的智慧结晶
  • PCIe | TLP 报头 / 包格式 / 地址转换 / 配置空间 / 寄存器 / 配置类型
  • 第二章:一致性基础 A Primer on Memory Consistency and Cache Coherence - 2nd Edition
  • 线程互斥与同步(上)
  • 2025年渗透测试面试题总结-拷打题库36(题目+回答)
  • Python Cookbook-6.18 用__init__参数自动初始化实例变量
  • 多端定制系统开发:打造高效全平台覆盖的APP解决方案
  • Python爬虫(16)Python爬虫数据存储新维度:Redis Edge近端计算赋能实时数据处理革命
  • phpyun人才系统v7.0升级v7.1 开源vip版,php云专业人才招聘系统小程序零工市场源码支持v4.6的更新步骤流程详解
  • 工作记录 2015-07-15
  • 数据结构的基本概念以及算法的基本内容
  • python:如何获取股票 周K线数据、月K线数据
  • Go语言入门基础:协程
  • 【信息系统项目管理师-论文真题】2012上半年论文详解(包括解题思路和写作要点)
  • 装饰器@wraps(func)详解
  • 伊甸园之东: 农业革命与暴力的复杂性
  • Learning vtkjs之Cutter
  • 有向图强连通分量好题分享(一)
  • 【深度学习的灵魂】图片布局生成模型LayoutPrompt(2)·布局序列化模块
  • 如何通过文理工三类AI助理赋能HI,从而,颠覆“隔行如隔山”的旧观念和“十万小时定律”的成长限制
  • 快速掌握--cursor