0

0

如何在集合框架中处理并发计数_Map与LongAdder的高效组合

P粉602998670

P粉602998670

发布时间:2026-02-20 13:37:02

|

459人浏览过

|

来源于php中文网

原创

concurrenthashmap + longadder 更快是因为longadder将累加分散到多个cell,避免高并发下的cas重试竞争;而concurrenthashmap的compute/merge仍存在锁或cas冲突,尤其在万级tps时cpu大量耗在重试上。

如何在集合框架中处理并发计数_map与longadder的高效组合

为什么 ConcurrentHashMap + LongAdder 比直接用 ConcurrentHashMap<long></long> 更快

因为 ConcurrentHashMapcomputemerge 方法在高并发下仍会触发锁竞争(哪怕只是分段锁或 CAS 重试),而 LongAdder 把计数分散到多个单元,写操作几乎无冲突。你不是在“更新一个值”,而是在“往不同槽里加一”,最后才汇总——这对高频累加场景就是质变。

常见错误现象:ConcurrentHashMap.compute(key, (k, v) -> v == null ? 1L : v + 1) 在万级 TPS 下 CPU 花费大量时间在 CAS 失败重试上,LongAdder.sum() 却稳定低开销。

  • 适用场景:统计请求量、缓存命中次数、接口调用量等纯累加型指标
  • 不适用场景:需要原子读-改-写(比如“如果小于阈值才加”)、或要求严格实时一致性的计数
  • LongAdder 不是线程安全的“变量替代品”,它不能直接当 long 用;必须用 sum()longValue() 获取当前值

怎么把 LongAdder 存进 ConcurrentHashMap 并避免内存泄漏

不能直接 new 一个 LongAdder 放进去就完事——如果 key 长期不访问,对应 LongAdder 实例会一直占着内存,且 ConcurrentHashMap 不会自动清理未使用的计数器。

正确做法是结合 computeIfAbsent 按需创建,并配合弱引用或定期清理逻辑(视业务周期而定):

ithy
ithy

融合多种AI模型的AI搜索平台

下载
Map<String, LongAdder> counters = new ConcurrentHashMap<>();
// 安全获取并累加
counters.computeIfAbsent("api/login", k -> new LongAdder()).increment();
  • 每次 computeIfAbsent 都是无锁路径,只有首次 put 时才可能有轻微竞争
  • 不要用 getOrDefault(key, new LongAdder()) —— 这会每次新建实例,造成对象爆炸和 GC 压力
  • 如果 key 有明确生命周期(如用户 session ID),建议搭配 ScheduledExecutorService 定期扫描过期 key 并 remove

ConcurrentHashMap 的遍历与快照一致性问题

ConcurrentHashMap 迭代器是弱一致的,遍历时其他线程仍在写 LongAdder,所以你拿到的 sum() 只是那一刻的近似值——这不是 bug,是设计使然。

如果你需要“某一时刻所有计数器的总和”,不能边遍历边加,而要先收集所有 LongAdder 引用,再统一调用 sum()

List<LongAdder> adders = new ArrayList<>(counters.values());
long total = adders.stream().mapToLong(LongAdder::sum).sum();
  • 避免在遍历 entrySet() 时直接调用 getValue().sum() —— 中间可能被其他线程修改,结果不可重现
  • LongAdder.sum() 是非阻塞的,但多次调用之间没有顺序保证;一次收集 + 一次批量 sum 才接近“快照”语义
  • 如果对一致性要求极高(比如计费场景),这种组合就不适合;该换 StampedLock + long[] 或专用指标库(如 Micrometer)

LongAdder 和 AtomicLong 在什么情况下反而更慢

当并发度极低(比如单线程反复调用),LongAdder 的内部 cell 分配、跳转、分支预测开销反而比 AtomicLong 的单 CAS 更重。

  • 实测显示:QPS AtomicLong.incrementAndGet() 通常快 10%–20%
  • LongAdder 的优势从几百次/秒写操作开始显现,在数千以上才真正拉开差距
  • 别为了“看起来高级”强行替换;压测你的实际负载路径,看 ThreadMXBean.getThreadCpuTime() 或 Arthas trace 结果

最易被忽略的一点:LongAdder 的内存占用是 AtomicLong 的数倍(默认最多 128 个 cell),小堆或大量 key 场景下容易推高 GC 频率——不是所有“高效”都只看吞吐。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

790

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

246

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

806

2024.03.01

session失效的原因
session失效的原因

session失效的原因有会话超时、会话数量限制、会话完整性检查、服务器重启、浏览器或设备问题等等。详细介绍:1、会话超时:服务器为Session设置了一个默认的超时时间,当用户在一段时间内没有与服务器交互时,Session将自动失效;2、会话数量限制:服务器为每个用户的Session数量设置了一个限制,当用户创建的Session数量超过这个限制时,最新的会覆盖最早的等等。

328

2023.10.17

session失效解决方法
session失效解决方法

session失效通常是由于 session 的生存时间过期或者服务器关闭导致的。其解决办法:1、延长session的生存时间;2、使用持久化存储;3、使用cookie;4、异步更新session;5、使用会话管理中间件。

773

2023.10.18

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

97

2025.08.19

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1536

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

443

2025.10.17

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

796

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号