Introduction to Singleton Pattern in Java with Examples

The singleton pattern is a design pattern that restricts the number of instances of a class to one; at a given point of time there should be only one instance of the given class. A design pattern is a general reusable solution to a commonly occurring software design problem. You can read more about design patterns @ what-are-design-patterns

Singleton pattern is used when exactly only one object of a class is needed for activities like coordinate actions across the system, storing all your databse connection details at one place and retrieving through a lookup from various parts of your code etc. Having multiple objects with same data floating here and there can also result in inconsistency. Creating lot of unnecessary objects might take extra time and space also. Device drivers, Thread pools, cache, dialog boxes, registry settings, logging objects etc. are usually shared by the complete application and hence a singleton object cab be used to store those details. The singleton concept is sometimes generalized to systems that operate on a certain fixed number of objects; not just one. Other patterns like Abstract Factory, Builder, and Prototype patterns can use Singleton concept in their implementation.

We will cover some of the popular java singleton implementations in this article. 

Single-element enum type approach for singleton

If you are using Java 5 or above and if you don’t want lazy initialization, a single-element enum type is the best way to implement a singleton. It gives guarantee against almost all problems that might occur during synchronization, serialization etc.

Example:

public enum Singleton {

INSTANCE;

//Any members like a normal class.

}

If you are not familiar with enums in Java, you can read the article enums-in-java-with-examples.

Advantages

When you use enums you don't have to worry about many things like synchronization, reflection attacks etc. which you will see soon.

Limitations

Only significant limitation with Enums is that we can’t do a lazy initialization. Lazy initialization means delaying the initialization of a field, here our sigleton object, until it is needed. If a field is never used, it will never get initialized. Though decreases the cost of initializing a costly object if not needed, tt increases the overhead of lazily initializing a field or object. So best advice is not to use lazy initialization unless you need it.

So if you need lazy initialization you need to do it using a class. Let us discuss some approaches here.

Singleton lazy initialization basic approach

We need to ensure that only one object is created for a class. Hence we will not give user the option to create an object for the class, instead user will call a method (e.g. getInstance()) that will return him the object. The method will create an object (lazily) when someone requests for an object for the first time. From the second time, the getInstance() method will return the object created in the first request.

 public class Singleton{

  private static Singleton INSTANCE;

  ...

  public static Singleton getInstance()

  {

    if(INSTANCE==null)

    {

      INSTANCE = new Singleton();

    }

    return INSTANCE;

  }

}

Limitations

Things are not that easy and straight forward as you think. You need to take care of many issues related to concurrency, reflection, serialization etc. and the most important one is related to concurrency. Consider thread-1 calls getInstance() and getInstance() sees that the variable INSTANCE is not initialized and starts the initialization process using new keyword. Before the object initialization is completed, and the created object is assigned to the variable INSTANCE, if a thread thread-2 call getInstance(), getInstance() sees that the variable INSTANCE is not yet initialized and starts the initialization process using new keyword again. Thus more instances of the class will be created which is against the singleton design pattern. A simple solution will be to synchronize the getInstance() method, but this is not a good solution as synchronization is only required during object creation and not required for returning the created object. We will see some of the approaches that take care of this concern.

Lazy initialization of singleton using static inner class

This methos is also called as 'lazy initialization holder class idiom'. For doing lazy initialization, we can have a public static inner class that holds only one declaration of a public static final variable of type of the singleton class initialized to the singleton instance. A static factory can return this singleton reference. Java spec guarantee that a class will be initialized only when it is accessed for the first time. So the inner class will be initialized only when the getInstance() method accesses it. Note that ou also need a private constructor to avoid anyone else outside from creating an instance of this class or overriding it.

public class Singleton{

  private Singleton(){…}

  public static class SingletonHolder {

    public static final Singleton INSTANCE = new Singleton();

  }

  public getInstance(){

    return SingletonHolder.INSTANCE;   

  }

  …

}

Advantage

Since you are indirectly making use of a JVM guarantee you are giving some of the responsibilities like concurrent thread access issues to the JVM implementation.

Lazy initialization of singleton using double check locking idiom

double check locking idiom is a very popular way of implementing singleton and hence we will discuss that also here now. A double check locking idiom checks the instance twice once without synchronization and once with synchronization. The single instance variable should be volatile for this idiom to work correctly. 

public class Singleton{

  private static volatile Singleton INSTANCE;

  ...

  public static Singleton getInstance()

  {

    if(INSTANCE==null)

    {

      synchronized(Singleton.class)

      {

        if(INSTANCE == null)

          INSTANCE = new Singleton();

      }

    }

    return INSTANCE;

  }

}

Also, if you need to use lazy initialization on an instance field, you can use a modified version of this with a factory method in a helper class.

Item 71 of Effective Java 2 by Joshua Bloch explains this as: "Prior to release 1.5, the double-check idiom did not work reliably because the semantics of the volatile modifier were not strong enough to support it [Pugh01]. The memory model introduced in release 1.5 fixed this problem [JLS, 17, Goetz06 16]. Today, the double-check idiom is the technique of choice for lazily initializing an instance field. While you can apply the double-check idiom to static fields as well, there is no reason to do so: the lazy initialization holder class idiom is a better choice."

Now let us see some more things that you can take care to make sure your singleton is always a singleton.

Defense against reflection attacks against singleton

Above simple solution does not prevent reflection based way of creating a class as:

Singleton singleton = null ;

Constructor[]  cs = Singleton.class.getDeclaredConstructors();

for ( Constructor c : cs ){

  c.setAccessible( true );

  singleton = (Singleton)c.newInstance();

  break;

}

One possible way to overcome this is by throwing an exception from the constructor if there is already an instance. So even if an outsider get access to the constructor, it will still fail with an exception.

private JavaSingleton() {

  if(INSTANCE != null) {

    throw new IllegalStateException("instance already created.");

  }

}

However one problem here is that since we are throwing an exception in the constructor, we’d need to be certain that the first call to the constructor comes from within the class, or else the single instance could belong to a wrong class. Since this issue occurs only when constructor is called from anywhere than through a factory, I am looking if we can check within the constructor, the identity of the caller, say using new Throwable().getStackTrace(), and throw an exception if that is not the intended caller class and method. A possible solution I found from google is to create a policy file that defines which callers have access and then add code in the constructor that checks to see if the caller has access. Please search in google for more details.

Using Singleton with serialization

Though it is always advisable not to implement Serializable for a singleton class, if you do implement, then you have to take care of some very important things. Two most important things are:

  1. Return the current instance than the newly created instance from the readResolve method, thus making the newly created instance by serialization eligible for garbage collection.
  2. All your instance fields should be declared transient.

It would be also good to write the readObject method as well and just call the defaultReadObject method on the ObjectInputStream.

Summary

You need to figure out whether you really need a singleton, if yes, whether you really need lazy initialization; and also what level of security you need and what level of complexity you can afford. There might be better alternate ways which I might not be aware. If you know any, please post it as a comment below. I have also not gone into complex scenarios like using it with multiple class loaders; and will add more details later.

Comments

Nice and very well explained!
'Defense against reflection attacks against singleton' is a completely new topic to me. Thanks for sharing!
I have recently read an old article which tells about the flaws of 'Double-Checked Locking'. It tells that the issue is not due to implementation bugs in JVMs but to the java platform memory model (Out-of Order writes) I don't know whether the recent versions of java addressed this issue or not. You can have a look into it.
http://www.ibm.com/developerworks/java/library/j-dcl/index.html
Many articles says (as you said), since java5, best and easy way is to use enum.
 

Was it useful?

As of Java 5, double-check idiom is safe with the use of volatile.

Item 71 of Effective Java 2 by Joshua Bloch explains this as: "Prior to release 1.5, the double-check idiom did not work reliably because the semantics of the volatile modifier were not strong enough to support it [Pugh01]. The memory model introduced in release 1.5 fixed this problem [JLS, 17, Goetz06 16]. Today, the double-check idiom is the technique of choice for lazily initializing an instance field. While you can apply the double-check idiom to static fields as well, there is no reason to do so: the lazy initialization holder class idiom is a better choice."

Was it useful?

Quick Notes Finder Tags

Activities (1) advanced java (1) agile (3) App Servers (6) archived notes (2) Arrays (1) Best Practices (12) Best Practices (Design) (3) Best Practices (Java) (7) Best Practices (Java EE) (1) BigData (3) Chars & Encodings (6) coding problems (2) Collections (15) contests (3) Core Java (All) (55) course plan (2) Database (12) Design patterns (8) dev tools (3) downloads (2) eclipse (9) Essentials (1) examples (14) Exception (1) Exceptions (4) Exercise (1) exercises (6) Getting Started (18) Groovy (2) hadoop (4) hibernate (77) hibernate interview questions (6) History (1) Hot book (5) http monitoring (2) Inheritance (4) intellij (1) java 8 notes (4) Java 9 (1) Java Concepts (7) Java Core (9) java ee exercises (1) java ee interview questions (2) Java Elements (16) Java Environment (1) Java Features (4) java interview points (4) java interview questions (4) javajee initiatives (1) javajee thoughts (3) Java Performance (6) Java Programmer 1 (11) Java Programmer 2 (7) Javascript Frameworks (1) Java SE Professional (1) JPA 1 - Module (6) JPA 1 - Modules (1) JSP (1) Legacy Java (1) linked list (3) maven (1) Multithreading (16) NFR (1) No SQL (1) Object Oriented (9) OCPJP (4) OCPWCD (1) OOAD (3) Operators (4) Overloading (2) Overriding (2) Overviews (1) policies (1) programming (1) Quartz Scheduler (1) Quizzes (17) RabbitMQ (1) references (2) restful web service (3) Searching (1) security (10) Servlets (8) Servlets and JSP (31) Site Usage Guidelines (1) Sorting (1) source code management (1) spring (4) spring boot (3) Spring Examples (1) Spring Features (1) spring jpa (1) Stack (1) Streams & IO (3) Strings (11) SW Developer Tools (2) testing (1) troubleshooting (1) user interface (1) vxml (8) web services (1) Web Technologies (1) Web Technology Books (1) youtube (1)