All about Singleton Design Pattern in Java

Singleton design pattern is a creational design pattern. The purpose of this design pattern is to control object creation.















Pro..
This pattern restricts the instantiation of the class and ensures that only one instance should be available in JVM.
Instance should be globally accessed.

Cons..
In cluster environment multiple instance per JVM or per node and JVM..which is not recommended to implement it.



Requirements:
1. JDK

2. Eclipse or any other editor

Let's discussed more about this:
1. Create the java project in eclipse:
2. Open the eclipse
3. Click File > New > Java Project
4. Enter the project name: Java-DesignPattern
5. Click on the Next
6. Click on the Finish.

Create the SingletonDesignPattern.java:
1. Right click on the src folder located under Java-DesignPattern
2. Click on the new > class
3. Enter the package name: com.tutorialbyexample
4. Enter the class name: SingletonDesignPattern
SingletonDesignPattern.java:

package com.tutorialbyexample;

import java.io.Serializable;

public final class SingletonDesignPattern implements Serializable {

       /**
        * Serial version UID, Suppose our class structure is changed after
        * serialization then when we will try to de-serialize, it will through
        * InvalidClassException. Nice to have serialVersionUID in such class.
        *
        */

       private static final long serialVersionUID = 1234567890999999999L;

       private String name = "Tutorial";

       /**
        * Volatile keyword in Java is used as an indicator to Thread that do not
        * cache value of this variable and always read it from main memory. If a
        * variable is not shared between multiple threads no need to use volatile
        * keyword with that variable. Another effect is the use of memory that is
        * local to a thread, so that changes aren't immediately visible to all
        * other threads. The consequence is that other threads can see inconsistent
        * states. volatile keyword is a kind of tool to control these effects.
        */

       private static volatile SingletonDesignPattern objSingletonDesignPattern = null;

       /**
        * IllegalStateException is thrown in order to prevent from instance
        * creation Using reflection, as private members can be accessed Using
        * reflection.
        */
       private SingletonDesignPattern() {
              if (objSingletonDesignPattern != null) {
                     throw new IllegalStateException(
                                  "Singleton instance already created");
              }

       }

       /**
        * Double-checked locking. Recheck the instance variable again in 
        * synchronized 
        * block
        */
       public static SingletonDesignPattern getInstance() {
              if (objSingletonDesignPattern == null) {
                     synchronized (SingletonDesignPattern.class) {
                           // Double check
                           if (objSingletonDesignPattern == null) {
                                  objSingletonDesignPattern = new SingletonDesignPattern();
                           }
                     }
              }
              return objSingletonDesignPattern;
       }

       /**
        * Overriding the clone() method to prevent of another instance.
        */
       @Override
       protected Object clone() throws CloneNotSupportedException {
              throw new CloneNotSupportedException(
                           "Won't be possible to clone this class");
       }

       /**
        * readResolve will stop creating another instance when we will try to
        * de-serialize the class. Distributed application environment, it is
        * frequently required to serialize the objects in file system, and read
        * them later whenever required. Note:- de-serialization always creates a
        * new instance. This method will be invoked when we will de-serialize the
        * object. readResolve will return existing instance to make sure single
        * instance in application.
        */
       protected Object readResolve() {
              return objSingletonDesignPattern;
       }

       /**
        *
        * @return
        */
       public String getName() {
              return name;
       }

       /**
        *
        * @param name
        */
       public void setName(String name) {
              this.name = name;
       }


}

PrintInfo.java

package com.tutorialbyexample.common;

public class PrintInfo {

/**
 * This is supporting method for printing
 * @param obj
 */
       public static void print(Object obj)
       {
              System.out.println(obj);
       }

}

SingletonDesignPatternClone.java

package com.tutorialbyexample;

import com.tutorialbyexample.common.PrintInfo;

/**
 *
 * @author Vinod Kumar
 *
 */
public class SingletonDesignPatternClone {
       public static void main(String args[]) throws Exception {

              // First instance created
              SingletonDesignPattern objSingletonDesignPattern = SingletonDesignPattern
                           .getInstance();
              PrintInfo.print("The first instance object is-"
                           + objSingletonDesignPattern);

              // Tryed to create another instance, with clone() method
              SingletonDesignPattern clone = (SingletonDesignPattern) objSingletonDesignPattern
                           .clone();
              PrintInfo.print("The clone instance object is-" + clone);
       }
}


SingletonDesignPatternReflection.java

package com.tutorialbyexample;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import com.tutorialbyexample.common.PrintInfo;

public class SingletonDesignPatternReflection {

public static void main(String[] args) throws InvocationTargetException {
try {
SingletonDesignPatternReflection objSingletonDesignPatternReflection = new SingletonDesignPatternReflection();
// Creating the first instance by .getInstance();
objSingletonDesignPatternReflection
.firstInstanceOfSingletonDesignPatternBygetInstance();
// Try to create another instance by reflection
objSingletonDesignPatternReflection
.secondInstanceOfSingletonDesignPatternByReflection();

} catch (SecurityException se) {
se.getMessage();
} catch (NoSuchMethodException nsme) {
nsme.getMessage();
} catch (IllegalArgumentException iae) {
iae.getMessage();
} catch (InstantiationException ie) {
ie.getMessage();
} catch (IllegalAccessException iae) {
iae.getMessage();
}
}

/**
* First instance by .getInstance method()
*/
private void firstInstanceOfSingletonDesignPatternBygetInstance() {

SingletonDesignPattern objSingletonDesignPattern = SingletonDesignPattern
.getInstance();
PrintInfo.print("The first instance is-" + objSingletonDesignPattern);
}

/**
* secondInstanceOfSingletonDesignPatternByReflection
* @throws SecurityException
* @throws NoSuchMethodException
* @throws IllegalArgumentException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private void secondInstanceOfSingletonDesignPatternByReflection()
throws SecurityException, NoSuchMethodException,
IllegalArgumentException, InstantiationException,
IllegalAccessException, InvocationTargetException {
Class<SingletonDesignPattern> objSingletonDesignPatternReflection = SingletonDesignPattern.class;
Constructor<SingletonDesignPattern> cons = objSingletonDesignPatternReflection
.getDeclaredConstructor();
cons.setAccessible(true);
SingletonDesignPattern objSingletonDesignPatternSecond = cons
.newInstance();
PrintInfo.print("The another instance is-"
+ objSingletonDesignPatternSecond);
}
}

SingletonDesignPatternSerialize .java

package com.tutorialbyexample;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

import com.tutorialbyexample.common.PrintInfo;

public class SingletonDesignPatternSerialize {
static SingletonDesignPattern objSingletonDesignPattern = SingletonDesignPattern
.getInstance();

public static void main(String[] args) {
try {

SingletonDesignPatternSerialize objSingletonDesignPatternSerialize = new SingletonDesignPatternSerialize();

// Writing data into file by Serialize
objSingletonDesignPatternSerialize.writeIntoFile();

objSingletonDesignPattern.setName("Tutoril By Example");

// DeSerialize from a file
PrintInfo.print(objSingletonDesignPattern.getName());
PrintInfo.print(objSingletonDesignPatternSerialize.readFromFile()
.getName());

} catch (IOException ioe) {
ioe.printStackTrace();
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* Serialized singlenton object into file.
* @throws IOException
* @throws FileNotFoundException
*/
private void writeIntoFile() throws IOException, FileNotFoundException {
// Serialize to a file
ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
"c:/SingletonDesignPattern.dat"));
out.writeObject(objSingletonDesignPattern);
out.close();

}

/**
* DeSerialized singlenton object from file.
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
private SingletonDesignPattern readFromFile() throws IOException,
ClassNotFoundException {
ObjectInput in = new ObjectInputStream(new FileInputStream(
"c:/SingletonDesignPattern.dat"));
SingletonDesignPattern objSingletonDesignPatternSecond = (SingletonDesignPattern) in
.readObject();
in.close();
return objSingletonDesignPatternSecond;
}

}


Please like and share it!!!


1 comment:

  1. Well explained in single place with all about singleton design pattern in Java.

    ReplyDelete

Please provide your input, it will honer for me...