首页 > 解决方案 > 如何用computeIfAbsent效率实现Map putIfAbsent语义?

问题描述

考虑以下代码:

ConcurrentHashMap<String, Value> map = new ConcurrentHashMap<>();

boolean foo(String key) {
    Value value = map.get(key);
    if (value == null) {
        value = map.putIfAbsent(key, new Value());
        if (value == null) {
            // do some stuff
            return true;
        }
    }
    // do some other stuff
    return false;
 }
    

假设foo()由多个线程同时调用。还假设调用new Value()很昂贵。代码很冗长,仍然会导致Value创建冗余对象。上述逻辑能否以保证不Value创建冗余对象的方式实现(即new Value()最多调用一次)?我正在寻找一个干净的实现 - 最少的代码而不显式获取锁。

computeIfAbsent可能是一个不错的选择,但是它的返回语义不符合所需的逻辑。

标签: java

解决方案


Some minimal code that does the job:

boolean foo(String key) {
    AtomicBoolean flag = new AtomicBoolean();
    Value value = map.computeIfAbsent(key, k -> {flag.set(true); return new Value();});
    if (flag.get()) {
        // do some stuff
    } else {
        // do some other stuff
    }
    return flag.get();
}

推荐阅读