Java Singleton Pattern


What is Java Singleton ?

Singleton is a design pattern. This designing style allows the programmer to create only one object of the class; even if more than one is created, it is not an error, but the code allows only one. In singleton class, there will be always only one object functioning, at a given time.

Advantages of Java Singleton

1. This style is useful when only one object instantiation is enough to do with all the operations and also when the system operates more efficiently when one instance exists.

2. If you would like to load all the values from database and set them into the members of a class and reuse them throughout the application without creating the object again and again (reusing the same object). For eg: you can define a database connection or a hash map of STD/ISD codes (or a hash map of all the cities/states) in a singleton class and access them using the singleton object across the application without creating or loading the resources again and again.

3. The Singleton’s purpose is to control object creation, limiting the number to one throughout its life. Singleton concept creates only one object even though you create multiple.

4. Since there is only one Singleton instance, any instance fields of a Singleton will occur only once per class, just like static fields. Singletons often control access to resources such as database connections or sockets.

5. One application is, Singalton classes can be used in multi user environment where shared resource are frequently used. For example, in Struts 1.0 all action classes work on singleton only. Another example, if you have a license for only one connection for your database or your JDBC driver has trouble with multithreading, the Singleton makes sure that only one connection is made or that only one thread can access the connection at a time.

In Java API, java.lang.Runtime is a Singleton class.

Disadvantages of Java Singleton

If implemented unnecessarily, this pattern puts needless constraints in circumstances where actually one instance for the whole class is not needed and imposes more global environment in the code.

Implementation

The singleton object always access global data. The global values (state) must be persistent between all operations. The singleton object is created through a method call (not from directly accessing a constructor). The method returns the object, if no object already exists earlier. The method is coded in such a way if an object is created earlier, it returns the reference of the same object. This is completely transparent (unknown) to the programmer. Not to allow the programmer to create the object directly (not through method call), the constructor is declared private. Some developers declare it protected also as private does not allow the access to unit test operations.

The developer should be a little careful with singleton operations in multithreaded environment. If the code includes simultaneous processing activities, the method should be made mutually exclusive (by declaring something like synchronized). The code should take care of not to allow, the developer, accidental cloning of singleton object.

4 steps to implement in singleton creation

  1. Make the constructor private not to be accessed directly
  2. Create a method that returns a singleton object
  3. Apply synchronization to the method to be thread-safe
  4. Override clone() method for not allowing to clone the singleton object

Following program on Java Singleton takes all the above 4 steps into consideration to create a singleton object. A Student class is taken to illustrate.

public class Student
{
  private int marks;                 // assigned with default 0
  private static Student std;        // assigned with default null

  private Student() 
  {     
     // some code if required
  }
  public static synchronized Student getMe()
  {
    if(std == null)
    {
      std = new Student();  
    }
    return std;
  }

  public Object clone() throws CloneNotSupportedException
  {
     throw new CloneNotSupportedException("Not allowed on this singleton object");
  }

  public static void main(String args[])
  {
      Student std1 = getMe();
      Student std2 = getMe();

      std1.marks = 50;
      std2.marks = 60;
      System.out.println("std1 marks when std2 changes: " + std1.marks);   // 60

      std1.marks = 70;
      System.out.println("std2 marks when std1 changes: " + std2.marks);    // 70

      System.out.println("\nstd1 hash code: " + std1.hashCode());
      System.out.println("std2 hash code: " + std2.hashCode());
  }
}

Java Singleton
Output Screenshot on Java Singleton Pattern

     private int marks;
     private static Student std;

In the Student class two global variables marks and std are declared of type int and Student. Reference variable std is made static simply for the reason to be accessed from the static main() method; else not required (of course, not suggestible also).

     private Student() 
     {     
       // some code if required
     }

Observe, the way of developing a singleton, declare the constructor private so that outside classes cannot create Student object directly and must go through a method call only to create. This is also another programming paradigm making "public methods and private variables".

     public static synchronized Student getMe()
     {
       if(std == null)
       {
         std = new Student();  
       }
       return std;
     }

getMe() method is declared public to allow the other classes to call the method freely and also static to have the facility of calling the method from main() without the help of an object.

First time when the method is called, as std is null, std is instantiated. Next time when called again the method, std is not again instantiated and instead the same std object, created earlier, is returned. It is checked every time in if condition. Moreover, the method is made synchronized to be thread-safe to work without any data inconsistency in multithreaded environment. For example, two different classes may call the getMe() method concurrently, these classes should be safe to get a singleton object.

     Student std1 = getMe();
     Student std2 = getMe();

Two objects std1 and std2 are obtained by calling getMe() method two times. Infact, they look two different objects; but only one as they refer the same object std. Let us prove this. Observe, when std1 changes its marks std2 is getting affected and when std2 changes std1 gets affected.

     System.out.println("\nstd1 hash code: " + std1.hashCode());
     System.out.println("std2 hash code: " + std2.hashCode());

As both std1 and std2 are same, their hashCode() method returned the same value. This is a good proof.

     public Object clone() throws CloneNotSupportedException
     {
       throw new CloneNotSupportedException("Not allowed");
     }

The clone() inherited from Object class is overridden with an exception message and this does not allow any class to clone the Student object.

The easiest implementation consists of a private constructor and a field to hold its result, and a static access or method with a name like getInstance().

The private field can be assigned from within a static initializer block or, more simply, using an initializer. The getInstance() method (which must be public) then simply returns this instance.

Another way to create singleton after java 1.5 is Enum Singleton.

  1. Creation of Enum instance is thread-safe(No need to take care of double locking)
  2. Enum Singletons handled Serialization by themselves

WHEN TO USE SINGLETON?

  1. If an object doesn’t have any state (say, no attributes, only methods)
  2. If an object has READ-ONLY state ( all attributes are final)
  3. If an object has shared state (attributes are present, but those are modified by many of the other objects)

In the above scenarios make your class as singleton, otherwise don’t go for singleton…

2 thoughts on “Java Singleton Pattern”

Leave a Comment

Your email address will not be published.