Saturday 21 June 2014

Singleton Design Pattern in java with example

        In this post, we will learn about Singleton design pattern principles, different ways to implement Singleton and some of the best practices for it’s usage.

       Singleton pattern restricts the instantiation of a class and ensures that only one instance of the class exists in the java virtual machine. The singleton class must provide a global access point to get the instance of the class. 

       Singleton pattern is used for logging, drivers objects, caching and thread pool. Singleton design pattern is also used in other design patterns like Abstract Factory, Builder, Prototype, Facade etc.

   To implement the Singleton Design Pattern,you do the following the things,
  1) private constructor - no other class can instantiate a new object.
  2) private reference - no external modification.
  3) public static method is the only place that can get an object.

 Below are the different approaches of Singleton pattern implementation and design.

Eager initialization

           In eager initialization, the instance of Singleton Class is created at the time of class loading, this is the easiest method to create a singleton class but it has a drawback that instance is created even though client application might not be using it.

Here is the implementation of static initialization singleton class.    

  public class EagerInitializer{
        
        private static final EagerInitializer instance = new EagerInitializer();

        //private constructor to avoid client applications to use constructor.
        private  EagerInitializer(){
        }
        public static EagerInitializer getInstance(){
              return instance;
        }
  }

           If your singleton class is not using a lot of resources, this is the approach to use. But in most of the scenarios, Singleton classes are created for resources such as File System, Database connections etc and we should avoid the instantiation until unless client calls the getInstance method. Also this method doesn’t provide any options for exception handling.

Static block initialization

           Static block initialization implementation is similar to eager initialization, except that instance of class is created in the static block that provides option for exception handling

 public class StaticInitializer {
        private static StaticInitializer instance ;
        //private constructor to avoid client applications to use constructor.
        private  StaticInitializer() {
        }
        static {
             try {
                 instance = new StaticInitializer();
             } catch(Exception e) {
                     throw new RuntimeException("Exception in static block");
             }
        }
        public static StaticInitializer getInstance() {
               return instance;
        }
 }

         Both eager initialization and static block initialization creates the instance even before it’s being used and that is not the best practice to use. So in further sections, we will learn how to create Singleton class that supports lazy initialization.

Lazy Initialization

           Lazy initialization method to implement Singleton pattern creates the instance in the global access method. Here is the sample code for creating Singleton class with this approach.


  public class LazyInitializer{

        private static LazyInitializer instance;

        //private constructor to avoid client applications to use constructor.
        private  LazyInitializer(){
        }
        public static LazyInitializer getInstance(){
              if(instance == null){
                       instance = new LazyInitializer();
              }
              return instance;
        }
  }

       The above implementation works fine incase of single threaded environment but when it comes to multithreaded systems, it can cause issues if multiple threads are inside the if loop at the same time. It will destroy the singleton pattern and both threads will get the different instances of singleton class. In next section, we will see different ways to create a thread-safe singleton class.

Thread Safe Singleton

       The easier way to create a thread-safe singleton class is to make the global access method synchronized, so that only one thread can execute this method at a time. General implementation of this approach is like the below class.


  public class ThreadSafe{

        private static ThreadSafe instance ;
                        
        //private constructor to avoid client applications to use constructor.
        private  ThreadSafe(){
        }

        public static synchronized ThreadSafe getInstance(){
               if(instance == null){
                     instance = new ThreadSafe();
               }
               return instance;
         }
  }

        Above implementation works fine and provides thread-safety but it reduces the performance because of cost associated with the synchronized method, although we need it only for the first few threads who might create the separate instances (Read: Java Synchronization). To avoid this extra overhead every time, double checked locking principle is used. In this approach, the synchronized block is used inside the if condition with an additional check to ensure that only one instance of singleton class is created.

           Below code snippet provides the double checked locking implementation

                 public static ThreadSafe getInstance(){
                          if(instance == null){
                                    synchonized(ThreadSafe.class){
                                             if(instance == null ){
                                                      instance = new ThreadSafe();
                                             }
                                     }
                           }
                           return instance;
                 }

                      Real time Examples for Singleton Design Pattern:---

JDBC Example using Singleton Design pattern:--

         We write a class (ConnectionFactory) which implements singleton pattern defining database connection configuration statements and methods to make connection to the database. Reason for making this class as singleton is, we can create one object of this class and can create many Connection objects (one factory, many objects).
package com.adnjavainterview;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class ConnectionFactory {
           //static reference to itself
         private static ConnectionFactory instance = new ConnectionFactory();
         public static final String URL = "jdbc:mysql://localhost/jdbcdb";
         public static final String USER = "YOUR_DATABASE_USERNAME";
         public static final String PASSWORD = " YOUR_DATABASE_PASSWORD";
         public static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";
              //private constructor
         private ConnectionFactory() {
                 try {
                        Class.forName(DRIVER_CLASS);
                  }
                  catch (ClassNotFoundException e) {
                        e.printStackTrace();
                  }
         }
    
         private Connection createConnection() {
                   Connection connection = null;
                   try {
                          connection = DriverManager.getConnection(URL, USER, PASSWORD);
                   }
                   catch (SQLException e) {
                           System.out.println("ERROR: Unable to Connect to Database.");
                   }
                   return connection;
         } 
    
         public static Connection getConnection() {
                 return instance.createConnection();
         }
 }

Thank you for visiting blog..

Related Post:--

9 comments:

  1. Hello Sir,

    Thanks for such wonderful articles.

    It helped me a lot.

    I have one doubt over here.

    public class LazyInitializer{
    private static final LazyInitializer instance = null;
    //private constructor to avoid client applications to use constructor.
    private LazyInitializer(){
    }
    public static LazyInitializer getInstance(){
    if(instance == null){
    instance = new LazyInitializer();
    }
    return instance;
    }
    }

    In above example
    instance is declared as static final.

    And we can assign value to static final variable either at the line of declaration or in the static block.

    But here you are assigning value to static variable in getInstance() method.

    As per my knowledge it will give compile time error.

    Can you please clear my doubt?

    Thanks in Advance.

    Regards,
    Sagar

    ReplyDelete
    Replies
    1. Thanks sagar...I corrected it.

      Delete
    2. Really nice article and well explained. But this is for single threaded applications. So what about multiple thread application. I found a really great explanation and solution there.

      Delete
  2. Nice Tutorial Anil, with real world example. it easy to understand for newbie.

    ReplyDelete
  3. How to restrict the object creation in java using singleton please refer this click here

    ReplyDelete
  4. "Great blog created by you. I read your blog, its best and useful information. You have done a great work. Super blogging and keep it up.php jobs in hyderabad.
    "

    ReplyDelete
  5. Great Blog Anil,its really helps lot .

    ReplyDelete
  6. Well explained . Great article on singleton pattern . There is also good singleton pattern example visit Singleton class example

    ReplyDelete