concurrenthashmap.merge() 的核心作用是将查旧值、算新值、存结果三步压缩为原子操作,支持线程安全的累加、覆盖或条件合并,底层通过 cas 或细粒度锁保障并发安全。

ConcurrentHashMap.merge() 的核心作用
它把「查旧值-算新值-存结果」三步压缩成一个原子操作,特别适合多线程下对同一键做累加、覆盖或条件合并。不像 HashMap.merge() 仅简化逻辑,ConcurrentHashMap.merge() 真正做到了线程安全:底层用 CAS 或细粒度 synchronized 锁住对应桶(bin),确保多个线程同时 merge 同一键时不会丢数据。
处理并发累加的典型写法
统计某类事件次数、金额总和、计数器递增等场景,直接用 Integer::sum 或自定义累加逻辑即可:
- 用
merge(key, 1, Integer::sum)实现线程安全计数,等价于(old, _new) -> old == null ? _new : old + _new - 累加 double 值可写
merge(key, inputRate, Double::sum),避免手动判空和类型转换 - 若初始值不是 0(比如要从 100 开始累加),就把第二个参数设为 100,函数仍用
Double::sum
合并两个 Map 时的关键控制点
把 map2 合并进 map1,行为由 remappingFunction 决定:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 用
(old, _new) -> _new表示“新值覆盖旧值” - 用
(old, _new) -> old == null ? _new : old + _new表示“有旧值则累加,无则设新值” - 返回
null会触发自动删除该键,例如(old, _new) -> old != null && old > 100 ? null : old
注意:ConcurrentHashMap 不允许 key 或 value 为 null,传入会立即抛 NullPointerException。业务中若有空值,必须提前过滤(如用 stream().filter(Objects::nonNull))或改用 compute() 方法。
性能与安全边界提醒
虽然 merge 是原子的,但仍有几个实际开发中容易踩的坑:
- 每次 merge 都会重新计算 hash 并定位桶,高频调用建议批量预聚合,再单次 merge
- remappingFunction 内部不要做耗时操作(如远程调用、IO),否则会阻塞整个桶的写入
- 如果需要更灵活的空值处理或复杂条件判断,
computeIfAbsent()或computeIfPresent()可能比 merge 更合适 - size() 返回的是近似值,高并发下不保证实时精确;如需准确实时总数,应配合
mappingCount()(返回 long 类型,更可靠)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










