In few articles, it says that using of volatile fixes the Double Checked Locking issue.
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper(); //Important
}
}
return helper;
}
}
But here even if we use volatile for helper field, how can this be a safe publication ?
I mean how could this guarantee that we won’t get an in-consistence Helper object?
Without volatile, because the initial
if (helper == null)is outside of a synchronized block, there is no visibility / consistency guarantee. In particular, it would be possible thathelperwould be not null but referred to an object that is only partially created.That is because
helper = new Helper()is not an atomic operation:helperWithout synchronization, an observing thread could see these operations in any order, in particular it could see 3 before 2.
By making
helpervolatile, you introduces a happens-before relationship (as defined by the Java Memory Model) between the write and the read, which ensures that if you see 3 from an observing thread, you will also see 1 and 2.In particular, any operations executed before the volatile write will be visible from the volatile read (if it is subsequent of course).