Why
tempWrapper
is required for correctness? Can't I just remove it and replace withhelperWrapper
.
Let's compare the following 2 versions:
Original version:
public Helper getHelper() {
var localVar = helperWrapper; // read #1 of helperWrapper
if (localVar == null) {
synchronized (this) {
...
}
}
return localVar.value;
}
Version where tempWrapper
is replaced with helperWrapper
:
public Helper getHelper() {
if (helperWrapper == null) { // read #1 of helperWrapper
synchronized (this) {
...
}
}
return helperWrapper.value; // read #2 of helperWrapper
}
Notice the number of reads of the shared variable helperWrapper
:
If the write to helperWrapper
happened in another thread, then the JMM treats such reads as kind of independent, i.e. it permits executions where the 1st read returns a non-null value and the 2nd read returns null
(in this example this will throw NPE).
Therefore the local variable is used to avoid the 2nd read of the shared variable helperWrapper
.