Building a singleton in Java

Oct 28, 2012

Usually, I don’t use singletons that objects need to fetch using a static method. I prefer using dependency injection to give each object what it needs. But for lower level concerns, like logging or security, it is common to use singletons that are accessible from a static method. Like the way you get a logger with SLF4J:

Loggerlogger=LoggerFactory.getLogger(HelloWorld.class);

The logger object is a singleton obtained via a static method.

So how should we implement those static methods to return a singleton?

Lazy or not?

The first question you need to ask is whether or not you need lazy initialiation of the singleton. According to Wikipedia, “lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed” (emphasis mine). So if building your singleton is not really expansive, there is probably no need to build it lazily. In that case, the easiest way to build a singleton is to use a static field:

Of course, if you prefer, you could add a getter to the class to return the instance instead of having it public.

The important thing about this singleton implementation is the use of a static field to hold the instance. Static fields are initialized once when the class is loaded. So INSTANCE will be unique because it will be instanciated only once. But beware of serialization and reflection hacks that could wreak havoc and make INSTANCE not unique anymore. Check Item 3 of Joshua Bloch’s excellent Effective Java 2nd Edition for details.

If you are using Java 1.5+, maybe the best approach to create a singleton is by using enums:

publicenumEnumSingleton{INSTANCE;}

To get the instance:

EnumSingleton.INSTANCE;

The advantage of this method is that the singleton is guaranteed to be unique, even in the face of serialization or reflection. And you have to admit it is very simple!

According to Michael Borgwardt in this Stackoverflow answer, 99.99% of the time, this is all you need to build a singleton in Java. I’m sure that 99.99% is more a figure of speech than a scientifically validated number, but you got the idea!

I’m lazy!

If your singleton is really that expensive to build, maybe you want to defer its creation to the moment it is first accessed.

One challenge when implementing a lazy-initiliazed singleton is to correctly handle multiple threads. For a singleton that is expansive to build, we want the first thread that needs it to trigger its creation, while all other threads that need the singleton afterward to simply grab it. We don’t want to have multiple threads triggering the creation of multiple singletons (it won’t be a singleton anymore!).

Probably the most simple way to acheive this is to synchronize the method use to get and build the singleton, like this:

Nothing complicated about this. For many implementations that needs lazy initialization, this is perfectly fine. The main drawback of it is that under heavy thread usage, it might be a performance bottleneck (but please, do profile before jumping to that conclusion). As we can see, the whole getInstance method is synchronized, but what we really need to protect is the creation of the singleton. Once it is created, there is no need for the method to be synchronized anymore. How can we acheive this?

As we can see, the creation of the singleton is protected by a synchronized block. But the method itself is not. Once the singleton is built, the INSTANCE is returned and the synchronized block won’t be used anymore. Intituively, it seems to be ok. The main problem with this is, well, it don’t work in Java! Because of memory visibility and reordoring of instructions by the compiler and/or runtime, even if a thread sees the INSTANCE as non-null, it might not be properly initialized yet (as if the constructor as not been run). See the famous The “Double-Checked Locking is Broken” Declaration for more details.

But wait! Thanks to changes in the Java memory model from version 1.5, you can make double-checked locking work by either making INSTANCE volatile, or by making sure the Singleton class is immutable. See again the Declaration for details.

That method is called Initialization-on-demand holder. Notice that the singleton is hold by a private static class. But is it lazy and thread-safe? Will the singleton only be initialized on the first call to getInstance? Quoting Brian Goetz:

This idiom derives its thread safety from the fact that operations that are part of class initialization, such as static initializers, are guaranteed to be visible to all threads that use that class, and its lazy initialization from the fact that the inner class is not loaded until some thread references one of its fields or methods.

So INSTANCE will only be initialized the first time it is accessed and all other threads will get the initialized INSTANCE afterward. The beauty of this method is its simplicity. Less code and no synchronized. And according to Brian Goetz, it is faster.

In Item 71 of Efective Java 2nd Edition, Joshua Bloch recommends this last method for lazy initialization of a static field. For lazy initialization of instance fields, he recommends to use double-checked locking (of course, only if you really need it).

Conclusion

Like I said in the introduction, in general, I think it is best to use dependency injection instead of singletons accessible from a static method. But if you do decide that it is what you need, you should go with the simplest solutions, like a singleton initialized on a static field.