Sunday, 3 May 2015

Singleton Design Pattern in java with examples

Most of interviewer will be asking "do you know any design pattern"? Most of will be answering Singleton Design Pattern because even java beginners should know this pattern.

Here 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.




 Next,we will learn the different approaches of Singleton pattern implementation and design.



Eager instantiation using implementation with static field.
           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.



//Eager instantiation using implementation with static field.   
            public class EagerInitializer{
                     private static final EagerInitializer instance = new EagerInitializer();
                             //private constructor to avoid client applications to use constructor.
                     private  EagerInitiazer(){
      System.out.println("EagerInitiazer(): Initializing Instance");
                     }
                     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 final StaticInitializer instance ;
                             //private constructor to avoid client applications to use constructor.
                        private  StaticInitiazer(){
                        }
                        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.


//Lazy instantiation using implementation with static field.
              public class LazyInitializer{
                      private static final LazyInitializer instance = null;
                            //private constructor to avoid client applications to use constructor.
                      private  LazyInitiazer(){
                      }
                      public static LazyInitializer getInstance(){
                              if(instance == null){
         System.out.println("getInstance(): First time getInstance was invoked!");
                                      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 final ThreadSafe instance = null;
                        //private constructor to avoid client applications to use constructor.
                    private  ThreadSafe(){
                    }
                    public static synchronized ThreadSafe getInstance(){
                            if(instance == null){
       System.out.println("getInstance(): First time getInstance was invoked!");
                                     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 ){
            System.out.println("getInstance(): First time getInstance was invoked!");
                                                      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 in.blogspot.java2bigdata;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class ConnectionUtil {
           //static reference to itself
         private static ConnectionUtil instance = new ConnectionUtil();
         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 ConnectionUtil() {
                 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();
         }
 } 
 
 
Q: Which classes in JDK uses singleton pattern?
A: java.lang.Runtime : In every Java application there is only one Runtime instance that allows the application to interface with the environment it is running. The getRuntime is equivalent to the getInstance() method of the singleton class.

Q: Can the singleton class be subclassed?
A: Frankly speaking singleton is just a design pattern and it can be subclassed. However it is worth to understand the logic or requirement behind subclassing a singleton class as the child class might not inherit the singleton pattern objective by extending the Singleton class. However the subclassing can be prevented by using the final keyword in the class declaration.

If you know anyone who has started learning Java, why not help them out! Just share this post with them. Thanks for studying today!...

No comments:

Post a Comment