At this tutorial (link) on Java's volatile declaration is this example:
public class BackgroundFloobleLoader {
public volatile Flooble theFlooble;
public void initInBackground() {
// do lots of stuff
theFlooble = new Flooble(); // this is the only write to theFlooble
}
}
public class SomeOtherClass {
public void doWork() {
while (true) {
// do some stuff...
// use the Flooble, but only if it is ready
if (floobleLoader.theFlooble != null)
doSomething(floobleLoader.theFlooble);
}
}
}
It is said that the background thread is loading from a database so I think the author means the instantiation new Flooble()
takes a significant amount of time.
To quote: Without the theFlooble reference being volatile, the code in doWork() would be at risk for seeing a partially constructed Flooble as it dereferences the theFlooble reference.
How can it be? I would have expected the opposite. That is, I would have expected that without the volatile declaration the thread invoking doWork
method would be at risk of seeing the Flooble belatedly or never at all.
It can be caused by compiler reorderings. Compiler can inline Flooble
's constructor and change order of initialization of its fields and assigning reference to theFlooble
variable.
Declaring theFlooble
volatile prevents such reorderings.
See https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html