CCC*_*CCC 8 java collections concurrency multithreading hashmap
我有以下代码:
public class Cache {
private final Map map = new ConcurrentHashMap();
public Object get(Object key) {
Object value = map.get(key);
if (value == null) {
value = new SomeObject();
map.put(key, value);
}
return value;
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:地图put和get方法是线程安全的,但由于整个块未同步 - 多个线程可以两次添加相同的密钥吗?
put并且get在某种意义上是线程安全的,即从不同的线程调用它们不能破坏数据结构(例如,可以正常java.util.HashMap).
但是,由于块未同步,您可能仍有多个线程添加相同的密钥:两个线程都可以通过null检查,一个添加密钥并返回其值,然后第二个将使用新的值覆盖该值并返回它.
小智 7
从Java 8开始,您还可以使用以下方法防止添加重复的键:
public class Cache {
private final Map map = new ConcurrentHashMap();
public Object get(Object key) {
Object value = map.computeIfAbsent(key, (key) -> {
return new SomeObject();
});
return value;
}
}
Run Code Online (Sandbox Code Playgroud)
该API文档状态:
如果指定的键尚未与某个值关联,则尝试使用给定的映射函数计算其值,除非为null,否则将其输入此映射。整个方法调用是原子执行的,因此每个键最多只能应用一次该功能。在进行计算时,可能会阻止其他线程在此映射上进行的某些尝试的更新操作,因此计算应简短而简单,并且不得尝试更新此映射的任何其他映射。
| 归档时间: |
|
| 查看次数: |
6397 次 |
| 最近记录: |