有没有办法只在密钥不存在的情况下运行一段代码ConcurrentHashMap,并将代码的结果保存到集合中?
我无法使用Java 8功能,因为我正在为Android开发.
此外,我想避免运行长操作,如果我不必,我不想打破集合的原子操作这样做.
没有确切的等价物,但通常的方法是这样的:
ConcurrentMap<Key,Value> map = ...
Value computeIfAbsent(Key k) {
Value v = map.get(k);
if (v == null) {
Value vNew = new Value(...); // or whatever else you do to compute the value
v = (v = map.putIfAbsent(k, vNew)) == null ? vNew : v;
}
return v;
}
Run Code Online (Sandbox Code Playgroud)
这在功能上与computeIfAbsentJava 8中的调用几乎相同,唯一的区别在于有时你构造一个Value永远不会进入地图的对象 - 因为另一个线程首先放入它.它永远不会导致返回错误的对象或类似的东西 - Value无论如何,函数始终返回正确的权利,但如果Value的构造具有副作用*,则这可能是不可接受的.
额外的实例通常不是性能问题,因为初始get()检查消除了大多数调用putIfAbsent.通常,这种方法可以比在对象已经存在时调用不必要的对象锁定快得多computeIfAbsent.如果有些物体严重争用,我在本地测量它的速度提高了5 倍.
如果你真的需要集成到地图中的计算行为(保持内部锁定,那么一个线程就会创建新对象),你可以使用Guava CacheBuilder来获得一个LoadingCache.它与Java 8的CHM基本相同,但有大量额外的配置选项.
| 归档时间: |
|
| 查看次数: |
1679 次 |
| 最近记录: |