使此代码段线程安全的最佳方法是什么?
private static final Map<A, B> MAP = new HashMap<A, B>();
public static B putIfNeededAndGet(A key) {
B value = MAP.get(key);
if (value == null) {
value = buildB(...);
MAP.put(key, value);
}
return value;
}
private static B buildB(...) {
// business, can be quite long
}
以下是我能想到的几个解决方案:
- 我可以使用 a
ConcurrentHashMap
,但如果我很好理解,它只会使原子put
和get
操作线程安全,即它不能确保buildB()
对于给定值只调用一次方法。 - 我可以使用
Collections.synchronizedMap(new HashMap<A, B>())
,但我会遇到与第一点相同的问题。 - 我可以设置整个
putIfNeededAndGet()
方法synchronized
,但是我可以让很多线程一起访问这个方法,所以它可能非常昂贵。 - 我可以使用双重检查锁定模式,但仍然存在相关的乱序写入问题。
我还有什么其他解决方案?
我知道这是网络上一个相当普遍的话题,但我还没有找到一个清晰、完整且有效的示例。