Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to Build Creational Design Patterns: Singleton Pattern

DZone's Guide to

How to Build Creational Design Patterns: Singleton Pattern

Want to learn more about using the singleton pattern from the creation design patterns? Check out this tutorial on singleton patterns with the Messenger class.

· Java Zone ·
Free Resource

How do you break a Monolith into Microservices at Scale? This ebook shows strategies and techniques for building scalable and resilient microservices.

The singleton design pattern is a software design pattern that restricts the instantiation of a class to one object. In comparison with other creational design patterns, such as the abstract factory, the singleton builder pattern will create an object and 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 to keep in mind:

  • 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?

For example, let's suppose that 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. Let's imagine a 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 send 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 where memory allocation only happens once when the class is loaded in the memory. In doing this, we ensure that the Messenger class will be instantiated only once. The getInstance method will fetch the static messenger instance once it is called.

Obviously, the previous approach has its pros and cons. We don’t have to worry about thread safety, and the instance will be created only when the Messenger  class will be loaded. However, it lacks flexibility. Let's consider the scenario of passing configuration variables to the Messenger constructor. You will find that 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 cases, but it misses 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 it all up,  we created an object and we also made sure that there will be only one instance of that object. We made sure that there won’t be any problems instantiating the object in a multi-threaded environment.

You can find the source code on GitHub.

How do you break a Monolith into Microservices at Scale? This ebook shows strategies and techniques for building scalable and resilient microservices.

Topics:
java ,design pattens ,singleton ,creational design patterns ,messenger

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}