I think the author in the presentation refers to the fact that a static field would be initialized only once in a thread-safe way at the first use of the class which contains that field (this is guaranteed by JMM):
class StaticLazyExample1 {
static Helper helper = new Helper();
static Helper getHelper() {
return helper;
}
}
Here helper
field would be initialized upon first usage of StaticLazyExample1
class (i.e. upon constructor or static method call)
There is also Initialization On Demand Holder idiom, which is based on static lazy initialization:
class StaticLazyExample2 {
private static class LazyHolder {
public static Helper instance = new Helper();
}
public static Helper getHelper() {
return LazyHolder.instance;
}
}
Here a Helper
instance would be created only upon first call to StaticLazyExample2.getHelper()
static method. This code is guaranteed to be thread-safe and correct because of the initialization guarantees for static fields; if a field is set in a static initializer, it is guaranteed to be made visible, correctly, to any thread that accesses that class.
UPDATE
What is the difference between both types of initialization?
The static lazy initialization provides efficient thread safe lazy initialization of the static fields and has zero synchronization overhead.
On the other hand if you would like to lazily initialize a non-static field, you should write something like this:
class LazyInitExample1 {
private Helper instance;
public synchronized Helper getHelper() {
if (instance == null) instance == new Helper();
return instance;
}
}
Or use Double-Cheked Locking idiom:
class LazyInitExample2 {
private volatile Helper helper;
public Helper getHelper() {
if (helper == null) {
synchronized (this) {
if (helper == null) helper = new Helper();
}
}
return helper;
}
}
Should I mention they both require explicit synchronization and carry additional timing overhead comparing to static lazy initialization?