class Foo {It is possible that to due to compiler-based reorderings helper reference will be initialised while the fields in Helper object will be at their default values. There are other more subtle problems with the double-checked locking approach. You can read the complete paper here.
private Helper helper = null;
public Helper getHelper() {
if (helper == null)
synchronized(this) {
if (helper == null)
helper = new Helper();
}
return helper;
}
}
In most cases such an optimisation is not worth the trouble. If you want to lazy-initialise a singleton, define it as a static field in another class:
class Helper {The semantics of Java guarantees that singleton field is going to be initialised only when referenced, and that all threads accessing the field will see the writes performed during the initialisation.
class HelperSingleton {
static Helper singleton = new Helper();
}
public Helper getHelper() {
return HelperSingleton.singleton;
}
}