java - 如何用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
可能是一个不错的选择,但是它的返回语义不符合所需的逻辑。
解决方案
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();
}
推荐阅读
- reactjs - 为什么我会收到此错误?错误:第一个参数是必需的,并且必须是or
- php - 使用 Ghostscript 转换时出现 PDF 错误
- python - 根据索引“月”和列将 DataFrame 值映射到另一个 DataFrame
- spring - Junit mockito when(..).thenReturn() NullPointerException
- snowflake-cloud-data-platform - 带有自定义电子邮件的资源监视器
- kivy - 缩进无效,必须是8个空格的倍数,圆角按钮kivy .kv文件
- java - 在不同线程中使用相同的 ExecutorService 实例是线程安全的吗?
- windows - 批处理选择命令运行两个选项,而不仅仅是我选择的那个
- c# - c# wpf 内存泄漏
- php - Composer 不会从私有 git 存储库克隆