Java:在嵌套ConcurrentHashMap中使用merge()实现值更新
优化嵌套ConcurrentHashMap的增量更新逻辑
嘿,我来帮你搞定这个嵌套ConcurrentHashMap的优化问题~首先得指出你原来代码里的一个坑:当外层hashMap已经存在"key"对应的嵌套Map时,你直接put了一个全新的ConcurrentHashMap,这会把原来的嵌套Map整个覆盖掉,丢失其他key的数据,这肯定不是你想要的对吧?
接下来咱们用merge()(结合链式调用或compute())来优化,既解决线程安全问题,又让代码更简洁:
方案一:链式调用merge(最简洁)
hashMap.merge("key", new ConcurrentHashMap<>(), (existingInnerMap, newInnerMap) -> existingInnerMap) .merge(longKey, 1L, Long::sum);
代码解释:
- 外层的
merge():- 检查外层
hashMap中是否存在"key":如果不存在,就把新建的ConcurrentHashMap作为value放进去;如果已经存在,直接返回原来的嵌套Map(第三个参数的lambda就是干这个的,返回existingInnerMap,忽略新创建的空Map)
- 检查外层
- 链式调用内层的
merge():- 对返回的嵌套Map,针对
longKey做增量更新:如果longKey不存在,就设置值为1L;如果已经存在,就把原有值和1L相加(Long::sum是方法引用,等价于(oldVal, newVal) -> oldVal + newVal)
- 对返回的嵌套Map,针对
方案二:用compute()整合逻辑
如果觉得链式调用不够直观,也可以用compute()把逻辑整合在一起:
hashMap.compute("key", (outerKey, innerMap) -> { // 确保内层Map存在:不存在就新建 if (innerMap == null) { innerMap = new ConcurrentHashMap<>(); } // 对内层Map的指定key做增量更新 innerMap.merge(longKey, 1L, Long::sum); return innerMap; });
代码解释:
compute()方法会原子性地处理外层key对应的value:要么新建内层Map,要么复用已有的- 然后对内层Map执行
merge()完成增量,整个过程是线程安全的,避免了原代码中containsKey()+get()这种非原子操作在高并发下的问题
对比原代码的优势:
- 不会覆盖整个内层Map,只会更新目标
longKey对应的值,保留其他数据 - 利用ConcurrentHashMap的原子方法(
merge()、compute())保证并发场景下的线程安全,不需要额外加锁 - 代码更简洁,省去了多层嵌套的条件判断
内容的提问来源于stack exchange,提问作者NoName
相关产品推荐
相关产品推荐

