Creational Design Patterns: Singleton Pattern
The singleton design pattern is a software design pattern the restricts the the instantiation of a class to one object.
In comparison with other creational design patterns such as the abstract factory, factory and the builder pattern the singleton will create an object but will also be responsible so that only one instance of that object exists.
When creating a class as a singleton there are some certain problems that is has to tackle.
- How can it be ensured that a class has only one instance.
- How can the sole instance of a class be accessed easily
- How can a class control its instantiation
- How can the number of instances of a class be restricted
Suppose we have a class that sends messages.
The Messenger class.
package com.gkatzioura.design.creational.singleton; public class Messenger { public void send(String message) { } }
However we want the message procedure to be handled only by one instance of the Messenger class. Imagine the scenario where the Messenger class opens a tcp connection (for example xmpp) and has to keep the connection alive in order to send messages. It will be pretty inefficient to open a new xmpp connection each time we have to sent a message.
Therefore we will proceed and make the messenger class a singleton.
package com.gkatzioura.design.creational.singleton; public class Messenger { private static Messenger messenger = new Messenger(); private Messenger() {} public static Messenger getInstance() { return messenger; } public void send(String message) { } }
As you can see we set the messenger constructor as private, and we initialized a messenger using a static variable.
Static variables are class level variables, memory allocation only happens once when the class is loaded in the memory. By this way we ensure that the messenger class will be instantiated only once. The getInstance method will fetch the static messenger instance once called.
Obviously the previous approach has its pros and cons. We don’t have to worry on thread safety and the instance will be created only when the Messenger class will be loaded. However it lacks in flexibility. Consider the scenario of passing configuration variables to the Messenger constructor. It is not possible using the previous approach.
A workaround is to instantiate the messenger class on the getInstance method.
package com.gkatzioura.design.creational.singleton.lait; public class Messenger { private static Messenger messenger; private Messenger() {} public static Messenger getInstance() { if(messenger==null) { messenger = new Messenger(); } return messenger; } public void send(String message) { } }
The above approach might work in certain case but it misses on thread safety in cases where the class might get instantiated in a multithreaded environment.
The easiest approach to make our class thread safe is to synchronize the getInstance method.
package com.gkatzioura.design.creational.singleton.lait; public class Messenger { private static Messenger messenger; private Messenger() {} public synchronized static Messenger getInstance() { if(messenger==null) { messenger = new Messenger(); } return messenger; } public void send(String message) { } }
That one will work. At least the creation of the messenger will be synchronized and no duplicates will be created. The problem with this approach is that the synchronization is only needed once when the object is created. Using the above code will lead to unnecessary overhead.
The other approach is to use the Double-Checked Locking approach. Now Double-Checked locking needs extra care since it is easy to pick the broken implementation over the correct one.
The best approach is to implement lazy loading using the volatile keyword.
package com.gkatzioura.design.creational.singleton.dcl; public class Messenger { private static final Object lock = new Object(); private static volatile Messenger messenger; private Messenger() {} public static Messenger getInstance() { if(messenger==null) { synchronized (lock) { if(messenger==null) { messenger = new Messenger(); } } } return messenger; } public void send(String message) { } }
By using the volatile keyword we prevent the write of a volatile to be reordered with respect to any previous read or write and a read of a volatile to be reordered with respect to any following read or write. Also a mutex object is used to achieve synchronization.
To sum up we created an object and we also made sure that there will be only one instance of that object. Also we made sure that there won’t be any problem on instantiating the object in a multi-threaded environment.
You can find the sourcecode on github.
On the next blog post we will have a look at the prototype pattern.
Also I have compiled a cheat sheet containing a summary of the Creational Design Patterns. Sign up in the link to receive it.
Published on Java Code Geeks with permission by Emmanouil Gkatziouras, partner at our JCG program. See the original article here: Creational Design Patterns: Singleton Pattern Opinions expressed by Java Code Geeks contributors are their own. |