Design Patterns: The Singleton

Kristo Godari
6 min readJul 9, 2019

In this story I will talk about the Singleton design pattern. What it is? Why is important? When to use it? and I will provide different implementations in Java language.

What is Singleton?

If you search in a dictionary the word Singleton (https://www.dictionary.com/browse/singleton) you will see that the first definition is: a person or thing occurring singly, especially an individual set apart from others. One other definition in Mathematics is: a set which contains exactly one element. This is the definition that we will talk about today.

In software the singleton patterns refers to the restriction of the instantiation of a class to a single instance per classloader.

Why we need Singleton pattern?

Why or when is useful to have only one instance of a class?

To answer this question first we let’s see what will happen with our application if we don’t use only one instance. Let’s take the classical example with the database connection objects. If we create a new object for each database connection, we will have a lot of database connection objects.

If we have a REST API that makes a query to the database, and let’s say that we have a traffic of 100 req/s, then we would will create 100 objects/s. If an database object is let’s say for the sake of the argument 100kb, then 100 req equals 10mb. We are filling the memory of our application with 10mb per second.

Not to mention that if you have an application with high traffic like 1000 req/s the things go crazier, you are filling the memory with 100mb per second, you will soon run out of memory. We are talking here only for the database connection object, in a real scenario you will have multiple objects in this situation.

At some point the garbage collection will kick in, this comes with a cost, the performance of your application will decrease.

Of course my example is exaggerated, i just wanted to point out the importance of not creating more objects that is needed.

The purpose of the singleton class is to control object creation, limiting the number of objects to only one. The singleton allows only one entry point to create the new instance of a specific class.

Another example for a singleton is when you have an app that uses an database of any kind and you need a connection pool. The purpose of such a pool is to reuse DB connection, so you definitely want all clients to use the same DB connection pool. Thus, having it as a singleton is the correct design.

The Singleton anti-pattern

The singleton was invented for the reasons that I described above, but it doesn’t mean that is suitable for every context, and that you should write every object as a singleton. More than that is considered as an anti-pattern.

Main reasons that is considered an anti-pattern are:

  • Singletons are difficult to test and write unit tests on them
  • The singleton pattern is especially difficult to implement correctly when taking multi-threading into account.
  • Singletons are bad when used with multi-threading because with just a single object, the options of threading are limited.

If you want to read more in detail about this topic you can check these two links:

This doesn’t mean that you shouldn’t use singleton at all, it is nevertheless an extremely common and popular pattern. You should use it carefully, only when you really need it.

Implementing the Singleton pattern in Java

There are multiple ways of implementing the singleton in Java, I will present them below and tell for each of them what disadvantages they have and how to fix them.

Eager initialization

This is the most simple method to make a singleton, in this case we are creating the instance on class loading. By making the constructor private we are not allowing other classes to instantiate the Singleton class, we have added the getInstance() method, that is used for returning the object created when the class is first loaded.

One of the drawbacks of this approach is that we are creating an instance even though client application may not be using it. This may be a problem in some cases and can create memory leak. To solve this we will need what is called a Lazy initialization singleton.

Lazy initialization

Lazy initialization refers to the idea of creating a resource only when you need it. In our case we don’t create the singleton if the getInstance() method is never called. On the first call of the getInstance() we create the singleton object and the next time this method is called, no new object will be created but will be returned the existing object.

This is much better then the first approach but we can still improve, think about using this in a multi threading environment, if two or more threads access the getInstance() method in the same time, more than one instance will be created. We need to make the singleton thread safe.

Thread safe Singleton

There are two ways to make the singleton thread safe.

  • Adding synchronized keyword to method signature
  • Double check locking method

Using synchronized on getInstance();

As we have made the getInstance() synchronized, all other threads will need to wait for the first thread to finish executing this method.

There are some cons of using this approach:

  • Slow performance because of locking overhead.
  • Unnecessary synchronization that is not required once the instance variable is initialized.

Using double check locking on getInstance();

To solve the performance issues, with the above code, instead of synchronizing the whole method, we only synchronize the code that initializes the singleton.

We need to check again inside the synchronized block if the singleton has been initialized by another tread or not, to avoid initializing more than one time the singleton.

It is possible that both threads enter the same time in the first if statement. The first one will enter the synchronized block, the second one will wait after the first thread, and then the second thread will also enter the synchronized block, if the second if statement wasn't there the singleton would have been initialized two times.

Reflection safe Singleton

You may think that we are done, but not yet. The above singleton is good but is not reflection safe. It is possible to use java reflection API to inject an instance of the singleton.

The solution for preventing this is simple, we need to check inside the constructor that the instance is not initialized. If we find that we already have an instance, it means that somebody is using reflection, so we just throw an run time exception.

Serializing the singleton

There is only one thing left and our singleton will be perfect. In some special cases we will need to serialize and deserialize the singleton. The problem is that during the deserialization process it will create a new instance of the singleton.

To fix this we have to provide the implementation of readResolve() method.The readResolve() replaces the object read from the stream.

Note

If you read with attention the code provided in this article, you will see that I have used the volatile keyword.

private static volatile SerializingTheSingleton singleton;

Why? Because reader threads are not doing any locking and until writer thread comes out of synchronized block, memory will not be synchronized and value of singleton will not be updated in main memory. With Volatile keyword in Java, this is handled by Java himself and such updates will be visible by all reader threads.

Singleton as Enum

In the last coupe of years a new approach has been popular that is to create singleton class by using enums. Since enums fields are compiled time constants, they are instances of their enum type. And, they’re constructed when the enum type is referenced for the first time.

Joshua Bloch has explained this approach in his Effective Java Reloaded talk at Google I/O 2008: https://sites.google.com/site/io/effective-java-reloaded

public enum Foo {
INSTANCE;
}

Conclusion

Singleton can be tricky to get it right, and if you are not careful it can easily become an anti-pattern. The easiest way and most simplest way to implement it is using Enums. Also the synchronized singleton, with reflection protection and serialization safe is good to use and should be fine for most applications.

Hopefully this article was useful and you learned something.

To let us know that this was useful, just clap ;)

--

--

Kristo Godari

Software Engineer with a passion for Software Architecture, I dream to design big, important, complex software systems. https://kristogodari.com/