有没有办法仅当密钥不存在时才运行一段代码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;
}
这在功能上几乎等同于computeIfAbsent
在 Java 8 中调用,唯一的区别是有时您会构造一个Value
永远不会将其放入映射中的对象 - 因为另一个线程首先将其放入。它永远不会导致返回错误的对象或类似的东西 - 该函数始终返回正确的对象Value
无论如何,但是如果 Value 的构建有副作用*,这可能不可接受。
额外的实例通常不是性能问题,因为初始实例get()
检查消除了大部分调用putIfAbsent
。一般来说,这种方法可以显着faster than computeIfAbsent
因为当对象已经存在时,该调用会对对象进行不必要的锁定。我本地测得是5times如果存在一些竞争激烈的对象,速度会更快。
如果您确实需要将计算行为集成到映射中(持有内部锁,以便只有一个线程创建新对象),您可以使用 Guava 的CacheBuilder https://google.github.io/guava/releases/16.0/api/docs/com/google/common/cache/CacheBuilder.html得到一个LoadingCache
。它本质上与 Java 8 的 CHM 行为相同,但具有大量附加配置选项。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)