回到并发.到目前为止,很明显,对于双重检查锁定,变量需要声明为volatile.但是,如果使用双重检查锁定,如下所示.
class Test {
private final Map map = new HashMap<>();
public B fetch(A key,Function loader) {
B value = map.get(key);
if (value == null) {
synchronized (this) {
value = map.get(key);
if (value == null) {
value = loader.apply(key);
map.put(key,value);
}
}
}
return value;
}
}
为什么它必须是ConcurrentHashMap而不是常规的HashMap?所有映射修改都在synchronized块中完成,代码不使用迭代器,因此从技术上讲,应该没有“并发修改”问题.
请不要建议使用putIfAbsent / computeIfAbsent,因为我在询问概念而不是使用API :)除非使用此API有助于HashMap与ConcurrentHashMap主题.
更新2016-12-30
Holger的评论回答了这个问题“HashMap.get没有修改结构,但你的put调用确实如此.因为在调用synchronized块之外调用get,它可以看到put的不完整状态行动同时发生.“谢谢!