The source code of design patterns can be viewed and downloaded here :
https://github.com/ebundy/java-examples/tree/master/design-patterns
What is it?
The singleton design pattern is a creational pattern.
It allows to instantiate a class under a simple condition : the existence of not more than one instance of the class.
The classical singleton design pattern relies on a class both responsible of ensuring the unique creation of the instance, providing a global point access to it and defining the core behavior of the class beyond its singleton nature.
When using it?
Creating singletons is a very common need.
For some classes, it is important, even essential to have one and only one instance of it because :
– it may be useless and a slight overhead. For example a repository class that proposes services to request a database has no reason to be created multiple times.
– it may break the logic of the application. For example a configuration class that
holds the state the application configuration should no be instantiated multiple times otherwise a configuration change performed on an instance could not be reflected by others.
– It may crash the application. For example it may be a fatal error to instantiate twice a class that consumes a lot of heap memory while it doesn’t need to be instantiated multiple times.
Another use case of the singleton pattern is when the singleton class is designed to be extensible and we want to use the singleton class both as a factory of itself and these subclasses and a global access point to.
Are singletons for mono or multi-threaded applications ?
Both can have classes implementing the singleton pattern.
But in general when we refer to the singleton pattern in OOP, we assume that the application runs in a multi-threaded environment where at least two threads may access in a concurrent way to an instance that is supposed to be a singleton.
If it was not the case, creating a singleton would be straight since no synchronization concern would be required : the object is created at the first request of it and then we return the created object for next requests. And all that without worrying about race conditions since a mono threaded application has no race condition for a resource.
Use classic singleton pattern with cautious
If implementing a classic singleton pattern is costly in terms of development, testability, readability or maintainability, we must be sure that the classic singleton pattern is really desirable before creating it. It may be an anti-pattern as the classic singleton pattern violates in a some way the single responsibility principle and may appear as a global instance harder to switch and to unit-test.
We must always assess advantages versus disadvantages when we use this pattern.
It is true for all patterns in general but it is still more true for this one particularly.
Alternative to the classic singleton pattern
With classic singleton pattern, the singleton class performs many tasks and implementing it may become cumbersome when we have to do it for many classes.
Dependency injection is a serious alternative to classic singleton pattern.
The dependency injection container relieves indeed singleton specific tasks : ensuring the unique creation of the instance and providing the point access to it in order that the class (that is a singleton instance) copes with a single thing : its core behavior.
How to implement a singleton?
If I write a bad implementation of the singleton, is it harmful?
If in some cases, it is harmless. In other cases, a bad singleton implementation may generate serious problems.
For example, we could have time response problems if the synchronization is more expensive than needed and is frequently used.
We could also have consistency and memory problems if multiple instances are created because of the singleton pattern has a broken implementation.
Is there an easy and generic way to implement singleton for multi-threaded applications ?
Yes. For example, Spring a library very used in the Java world today allows to create in a clean, simple and testable way singleton instances of our classes. Under the hood, it works with the dependency injection mechanism explained above.
If you use Spring in your application, it is often a very good thing to use it to implement your singletons.
If it’s not the case or you don’t want to use Spring for some reasons, there are simple and effective ways to implement by hand the singleton pattern. We will see that.
During many years, the way of implementing a singleton was not always an easy task for the average developer.
You often had the choice between a pseudo-singleton and a real singleton but with a implementation not really effective in terms of performance.
The performance problem was caused by a systematic synchronization when the singleton instance was accessed.
The singleton was implemented indeed by synchronizing the method responsible for returning the singleton and creating if it doesn’t existing yet.
So If the singleton was accessed thousands of times, a lock on the class was put thousands of times.
Costly singleton
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package davidhxxx.teach.designpattern.singleton; /* systematic synchronization when accessing */ public class SingletonCostly { private static SingletonCostly instance; private SingletonCostly() { } public static synchronized SingletonCostly getInstance() { if (instance == null) { instance = new SingletonCostly(); } return instance; } } |
In order to avoid this systematic lock, developers used multiple tricks. A very-known trick was the « double checking » method.
Unfortunately, this method didn’t give always a consistent instance of the singleton because the Java memory model of the JVM could not guarantee that.
It was related to the execution order performed by the JVM in a instruction like :
instance = new SingletonDoubleCheckedLocking();
In fact, in this assignment, there are multiple elementary instructions performed by the JVM.
Before JVMs for JDK 1.5, the execution order of them didn’t guarantee that the instance would have a constructor fully initialized before being assigned to a field.
For example, below in the sample code implementing a singleton with a double-checked locking, here is a scenario where the instance returned is broken.
Suppose 2 threads : thread A and thread B.
Thread A is at the line 13 but with its constructor not invoked yet : instance = new SingletonDoubleCheckedLocking();
so the instance field is not null but with only default value.
Thread A is paused and thread B is resumed. When thread B arrives at the line 12 :
if (instance == null) {
, the instance field being not null, it returns a not fully initialized instance since the constructor has not been invoked yet.
For more details on this subject :
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
Double-checked locking singleton
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package davidhxxx.teach.designpattern.singleton; //Broken multithreaded version before JDK 1.5 public class SingletonDoubleCheckedLocking { private static SingletonDoubleCheckedLocking instance; private SingletonDoubleCheckedLocking(){ } public static SingletonDoubleCheckedLocking getInstance() { if (instance == null) { synchronized (SingletonDoubleCheckedLocking.class) { if (instance == null) instance = new SingletonDoubleCheckedLocking(); } } return instance; } } |
In reality, at that time, there was a solution that is both working and efficient.
But, we would have known it to use it :)
Since the JDK 5 release, the memory model was modified in a fashion where the « double check » singletion implementation works.
Indeed, with this memory model, we can use the volatile keyword on the instance field storing the singleton. In this way, we ensure the creation of the singleton instance requested by a thread will always be done in a consistent way before any other thread may access to the singleton instance.
Instead of enumerating all ways of creating a singleton since Java 5, I prefer to interest to the way to do it in a clean and readable way whatever the java version used (JDK 5+ like JDK 1.4).
For example, the enum use (available since Java 1.5) presented by Joshua Bloch as the best solution to implement a singleton is certainly a very straight way and no verbose to do it but IHMO it is not necessarily the most readable and practical way to do it.
I see multiple drawbacks.
Firstly, an enum with a single value looks like a trick as it doesn’t enumerate values.
Secondly, enums are originally designed and actually more frequently used to represent enumeration of values and to perform very simple tasks associated to these values while the singleton is used in process and service classes that may perform a lot of logic.
Thirdly, a enum is a structure with more constraints than classes.
For example, an enum type cannot extend a class and cannot be extended either. It can only implement interfaces.
It may be a problem as process and service classes executing logic may need to benefit from the inheriting mechanism.
The solution I will present is IMHO one of the simplest and the most intuitive ways to implement the singleton pattern.
Bill Pugh (he is also the FindBugs’s author), is a computer science searcher in an university of the United States.
He is the author of several articles about the singleton implementation in JDK 1.4 and explanations why the double-checked locking and other tricks relying on this strategy are broken. He proposed an alternative to the double-checked locking which also works in Java 1.4.
Good news : the solution can be adapted for a lazy instantiation like an eager instantiation of our singleton.
The thread-safe validity of the implementation is guaranteed by the fact that the instantiation of a static field is always thread-safe.
So, contrary to the previous example with the double-check locking, even by using a version 1.4 of the JDK, we are sure that the instance field is fully initialized before becoming accessible to clients of the class.
For the lazy creation, we need two classes : the outer class which we want a singleton instance and an inner static class known as the holder class. We use the « holder » term because this class is responsible for holding the singleton instance.
The private static holder class owns an instance static field storing the singleton instance of the class.
The first time that the singleton instance is requested, that is when this method is invoked the first time :
public static SingletonBillPughWithLazyCreation getInstance() { return LazyHolder.instance; } |
the holder class is loaded since it is the first time the holder class is accessed :
return LazyHolder.instance; |
During the holder class loading, an instance of the outer class (the singleton) is created and assigned it to the instance static field :
private static SingletonBillPughWithLazyCreation instance = new SingletonBillPughWithLazyCreation(); |
For the next getInstance() calls, the unique created instance is returned.
Singleton BillPugh with lazy creation
package davidhxxx.teach.designpattern.singleton; public class SingletonBillPughWithLazyCreation { // Class responsible to create, store and get the singleton private static class LazyHolder { // executed only after the object instance is used by SingletonBillPughWithLazyCreation.getInstance() private static SingletonBillPughWithLazyCreation instance = new SingletonBillPughWithLazyCreation(); } private SingletonBillPughWithLazyCreation() { } public static SingletonBillPughWithLazyCreation getInstance() { return LazyHolder.instance; } } |
For the eager creation, it’s simpler since we don’t even need the holder class.
We instantiate the singleton instance in the declaration of the static field instance of the singleton class.
Singleton BillPugh with eager creation
package davidhxxx.teach.designpattern.singleton; public class SingletonBillPughWithEagerCreation { // executed as soon as the SingletonBillPughWithEagerCreation class is loaded by the classLoader private static SingletonBillPughWithEagerCreation instance = new SingletonBillPughWithEagerCreation(); private SingletonBillPughWithEagerCreation() { } public static SingletonBillPughWithEagerCreation getInstance() { return instance; } } |
Just one thing to say : big thanks to Bill Pugh !