繁体   English   中英

以原子方式确保ConcurrentMap条目

[英]Atomically ensuring a ConcurrentMap entry

在Java中,我经常需要懒洋洋地获取ConcurrentMap的条目,仅在必要时创建。

例如我可能有

ConcurrentMap<String, AtomicReference<Something>> a = new ConcurrentHashMap<>();
ConcurrentMap<String, Something> b = new ConcurrentHashMap<>();

我想创建一个通用函数来完成这项工作,这样我就不会为每种类型重复相当繁琐的双重检查代码

以下是我能得到的:

<K, V, C extends V> V ensureEntry(ConcurrentMap<K, V> map, K key, Class<? super C> clazz) throws Exception {
    V result = map.get(key);
    if (result == null) {
        final V value = (V)clazz.newInstance();
        result = map.putIfAbsent(key, value);
        if (result == null) {
            result = value;
        }
    }
    return result;
}

然后我可以像以下一样使用它:

AtomicReference<Something> ref = ensureElement(a, "key", AtomicReference.class);
Something something = ensureElement(b, "another key", Something.class);

问题是:函数非常脏,仍然有一个不安全的泛型类转换( (V) )。 一个完全通用和清洁的可能吗? 也许在斯卡拉?

谢谢!

使用Java 8 lambda,以下是我能得到的最简单的...

<K, V> V ensureEntry(ConcurrentMap<K, V> map, K key, Supplier<V> factory) {
    V result = map.get(key);
    if (result == null) {
        V value = factory.get();
        result = map.putIfAbsent(key, value);
        if (result == null) {
            result = value;
        }
    }
    return result;
}

ConcurrentMap<String, AtomicReference<Object>> map = new ConcurrentHashMap<>();
ensureEntry(map, "key", () -> new AtomicReference<>());
// or
ensureEntry(map, "key", AtomicReference::new);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM