Lazy initialization of singletons is overrated, usually not necessary and causes more problems than good. The naive approach to make the whole static getter synchronized
is bad, because the synchronization (which is a time consuming operation) is performed every time.
There are some better approaches such as double-checked locking or the initialization-on-demand holder, but the simplest and usually the best approach is Josh Bloch's enum approach. Make an enum
with a single element and you get a bullet proof singleton.
public enum Mongo {
INSTANCE;
// instance fields, methods etc. as in any other class
}
This is almost functionally equivalent to a class with a private
constructor and a public static final
instance, but with more concise syntax and some nice under-the-hood features that unshakeably guarantee that no other instance can be created, not even through reflection or deserialization.
It is worth noting that this approach isn't necessarily eager. The single INSTANCE
is created just after the Mongo
class is loaded into the JVM, which doesn't happed right after the program starts - actually it happens on the first time the class is referenced - which in this case means on the first time a static
field or a method is accessed.
And if there are no other static fields other that INSTANCE
and no static methods, then this really happens after the first time the INSTANCE
is accessed:
Mongo mongo = Mongo.INSTANCE;
In other words, it actually is lazy without the problems of explicit synchronization.