The obvious choice for implementing this type of lazy loading as of Java 5 is Double-Checked Locking. But after coding it up for the Hibernate SessionFactory, I realized I would have to do the same for the JPA and DB4O support. Given the relative complexity of DCL, that kind of sucks.
But then I remembered something Bob Lee said on Twitter the other day:

The man has a point.
I decided to roll our own utility class to lazily load object references. So I opened up the bible (Effective Java, 2nd edition) to look for the original pattern, and there it was. Page 283:
private volatile FieldType field;
FieldType getField() {
FieldType result = field;
if (result == null) { // First check (no locking)
synchronized(this) {
result = field;
if (result == null) // Second check (with locking)
field = result = computeFieldValue();
}
}
return result;
}
Scary. Now, there is no way we can reduce the size of that code much, but as it turns out we can make it a lot simpler to use. I called it LazyReference, here's an example usage:
private final LazyReference<SessionFactory> sessionFactory =
LazyReference.of(new Provider<SessionFactory>() {
public SessionFactory get() {
// code to create SessionFactory
}
});
To use this code, you just call sessionFactory.get(), and it will handle the lazy loading for you. Even if you are a Java master, there is no reason for you to repeat that complicated DCL code ever again. Enjoy!