In the new Java memory model, any write to a variable is guaranteed to be completed before the next thread read it.
I wonder if this is also the case for variables that are member of this object.
for java memory model:
http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html
E.g.
public class VolatileTest {
private volatile Map<String, Function> functionMap = new HashMap<>();
public Function getFunction(String key) {
Function function = this.functionMap.get(key);
if (function == null) {
//Is this guaranteed to be fully constructed? I don't think so.
function = new Function(key);
this.functionMap.put(key, function);
}
return function;
}
}
Like above code, even by making functionMap
volatile, it still doesn't guarantee the function object will be fully constructed before this method return.
Is my thinking right?
Also just for this topic, I'd like you guys to check is my thinking right for the following:
Like the below any write to the functionMap
is guaranteed to be completed before changing the reference of functionMap
, right? No matter how long the initializeMap
methods take, the other thread will either see a null functionMap
or a fully initialized functionMap
?
public Map<String,Function> getFunctionMap (){
Map<String, Function> tempMap = new HashMap<>();
initalizeMap(tempMap); //fill in values
// Above operation is guaranteed to be completed
// before changing the reference of this variable.
this.functionMap = tempMap;
// So here you will either see a null or a fully initialized map.
// Is my understanding right?
return this.functionMap;
}
Just to clarify above, above two examples are all in multi-thread environment and functionMap variables will be accessed by multiple thread.
This is exactly when ConcurrentHashMap should be used
private final ConcurrentMap<String, Function> functionMap = new ConcurrentHashMap<>();
public Function getFunction(String key) {
Function function = functionMap.get(key);
if (function == null) {
function = new Function(key);
Function oldFunction = functionMap.putIfAbscent(function);
if (oldFunction != null) {
function = oldFunction;
}
}
return function;
}