Different ways to write singleton in Java
In the second form, your singleton is eagerly loaded and this is actually the preferred form (and the first one isn't thread-safe as you mentioned it yourself). Eager loading is not a bad thing for production code but there are contexts where you might want to lazy load your singletons, as discussed by the author of Guice, Bob Lee, in Lazy Loading Singletons that I'm quoting below:
First, why would you want to lazy load a singleton? In production, you typically want to eagerly load all your singletons so you catch errors early and take any performance hit up front, but in tests and during development, you only want to load what you absolutely need so as not to waste time.
Before Java 1.5, I lazy loaded singletons using plain old synchronization, simple but effective:
static Singleton instance; public static synchronized Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; }
Changes to the memory model in 1.5 enabled the infamous Double-Checked Locking (DCL) idiom. To implement DCL, you check a
volatile
field in the common path and only synchronize when necessary:static volatile Singleton instance; public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) instance = new Singleton(); } } return instance; }
But
volatile
isn't that much faster thansynchronized
,synchronized
is pretty fast nowadays, and DCL requires more code, so even after 1.5 came out, I continued using plain old synchronization.Imagine my surprise today when Jeremy Manson pointed me to the Initialization on Demand Holder (IODH) idiom which requires very little code and has zero synchronization overhead. Zero, as in even faster than
volatile
. IODH requires the same number of lines of code as plain old synchronization, and it's faster than DCL!IODH utilizes lazy class initialization. The JVM won't execute a class's static initializer until you actually touch something in the class. This applies to static nested classes, too. In the following example, the JLS guarantees the JVM will not initialize
instance
until someone callsgetInstance()
:static class SingletonHolder { static Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; }
[...]
Update: Credit where credit is due, Effective Java (copyright 2001) detailed this pattern under item 48. It goes on to point out that you still have to use synchronization or DCL in non-static contexts.
I also switched singleton handling in my framework from synchronization to DCL and saw another 10% performance boost (compared to before I started using cglib's fast reflection). I only used one thread in my micro-benchmark, so the boost to concurrency could be even greater given that I replaced a heavily contended lock with a relatively fine grained volatile field access.
Note that Joshua Bloch now recommends (since Effective Java, 2nd ed) to implement singletons using a single-element enum
as pointed out by Jonik.
Well, in the latter case the singleton object gets created before it is ever needed, but in most cases that's probably not horribly bad.
By the way, Joshua Bloch recommends (in Effective Java, 2nd ed, item 3) implementing singletons using a single-element enum:
public enum SingletonObject {
INSTANCE;
}
He gives the following justification:
[...] it is more concise, provides serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.
I would say the latter code is the more standard pattern, actually. Your first version isn't thread-safe. Ways of making it thread-safe include synchronizing on every access, or very carefully making it use double-checked locking (which is safe as of the Java 5 memory model, so long as you get it right).
Note that due to classes being initialized lazily, your latter code would still only create an object unnecessarily if you called static methods on the class without wanting to create the instance.
There's a pattern using a nested class to do the initialization which can make this lazier, but personally the second form almost always does well enough for me on its own.
There are more details of this in Effective Java, but I don't have it with me to find the item number, I'm afraid.
The difference between your code and the "sample code" is that your singleton is instantiated when the class is loaded, while in the "sample" version, it is not instantiated until it is actually needed.