Do I need declare as volatile the supplier class member in order to preserve thread-safety
I am reading this book "Functional Programming in Java Harnessing the Power Of Java 8 Lambda Expressions" and in chapter 6 (lazy evaluations) there's an example of heavy object creation. Basically the example looks like this:
public class HeavyObjectCreation {
public static void main(String[] args) {
HeavyObjectCreation h = new HeavyObjectCreation();
h.getHeavy();
h.getHeavy();
h.getHeavy();
}
public static class Heavy {}
private Supplier<Heavy> heavy = this::createAndCacheHeavy;
public HeavyObjectCreation() {
}
public Heavy getHeavy() {
System.out.println("Getting heavy");
return heavy.get();
}
private synchronized Heavy createAndCacheHeavy() {
class HeavyFactory implements Supplier<Heavy> {
private final Heavy heavyInstance = new Heavy();
public Heavy get() { return heavyInstance; }
}
System.out.println("bypassing");
if(!(heavy instanceof HeavyFactory)) {
System.out.println("Creating heavy");
heavy = new HeavyFactory();
}
return heavy.get();
}
}
I was thinking whether I should declare "heavy" class member as volatile since it is accessed in two places: createAndCacheHeavy() which is synchronized and getHeavy() which is not synchronized. So my assumption is that there is no happens-before relationship between writing of "heavy" reference and reading it and that is why I think it should be declared as volatile:
private volatile Supplier heavy = ...
I would appreciate any help. Thanks!
P.S getHeavy() is invoked by other threads.