UrbanPro
true

Learn Java Training from the Best Tutors

  • Affordable fees
  • 1-1 or Group class
  • Flexible Timings
  • Verified Tutors

Search in

How to create a Singleton class?

GPCompTech
25/05/2017 0 0

How to create a Singleton class:

Q) What is a singleton class?

A) In simple words, a singleton class is a class which can have only one instance at any point of time throughout the application and provides a global point of access to its instance.

 

Q) How can you create a singleton class?

A)

class Singleton {

       public static final Singleton INSTANCE = new Singleton();

       private Singleton() {

       }

}

                 This is a simple example for a singleton class where I used a public static final INSTANCE variable and initialized it with a Singleton object. Since INSTANCE is public static final, it can’t be reassigned and it is thread safe as well.

                 Singleton’s constructor is made private to prevent the instantiation of Singleton class from other classes. That means no other class can create an object for Singleton class with the new() operator and also no other class can extend this Singleton class with extends keyword. If any class wants to have an instance of Singleton it can have by accessing INSTANCE field of Singleton class like Singelton. INSTANCE as its static.

 

  1. Q) So here, Singleton instance will be created at the time of class loading that means when the Singleton class is loaded by JVM into memory. So it’s an early loading/instantiation of Singleton class and it occupies memory even when its not required yet, so what If we want this singleton instance to be created when it’s really required?

 

  1. A) I understand that you are interested in lazy loading/instantiation of Singleton. Here it is

 

class Singleton {

       private static Singleton INSTANCE;

       private Singleton() {

       }

       public static synchronized Singleton getInstance() {

              if (INSTANCE == null) {

                     INSTANCE = new Singleton();

              }

              return INSTANCE;

       }

}

 

  1. Q) You synchronized the whole method

       public static synchronized Singleton getInstance()

Don’t you see any performance overhead with this approach?

Only one thread can access the method getInstance at a time to get the Singleton instance and rest of all other threads need to wait even though INSTANCE is not null as its already created.

A) Let me create it using synchronized block instead of synchronized method, here how it goes

 

class Singleton {

       private static Singleton INSTANCE;

       private Singleton() {

       }

       public static Singleton getInstance() {

              if (INSTANCE == null) {             //----- 1st

                     synchronized (Singleton.class) {

                           if (INSTANCE == null) {   //----- 2nd

                                  INSTANCE = new Singleton();

                           }

                     }

              }

              return INSTANCE;

       }

}

 

  1. Q) Why do you use null check twice here?
  2. A) I think I don’t need to explain you why did I use first null check, as you know I am going to create Singleton instance in case INSTANCE is null otherwise I ll return the already created instance.

2nd null check is being used to ensure thread safety.

For suppose, 2 threads are concurrently trying to get the access for getInstance() and two threads are gone through the 1st null check and trying to enter into synchronized block, but only one thread(assume thread-1) got the lock on Singleton.class’s  object and enters the synchronized block while the other thread (assume thread-2)waiting for the lock. Once thread-1 went through 2nd null check then it creates a Singleton instance as INSTANCE is null and leaves the synchronized block and thus releases lock. Now, the waiting thread ( thread-2) holds the lock and enters the synchronized block.

 

If there is no 2nd null check there then there is a chance for the thread-2 to create another instance of Singleton class and thus it breaks the singleton here. For that reason we have 2nd null check here. So the thread-2 sees that INSTANCE is not null and comes out from the synchronized block without creating Singleton instance.

 

  1. Q) Ok. So double checking is for thread safety of a singleton.

 

 

  1. A) yes

 

Q) Do you think that, this Singleton class is still singleton?

I can break your singleton with the help of reflection like below

 

public class Test {

       public static void main(String args[]) {

              Singleton singleton1 = Singleton.getInstance();

              Singleton singleton2 = null;

              try {

                     // Test is package name contains Singleton class

                     Class singletonClass = Class.forName("Test.Singleton");

                     // as we know there is only one private constructor

                     Constructor cons = singletonClass.getDeclaredConstructor();

                     cons.setAccessible(true);

                     singleton2 = (Singleton) cons.newInstance();

                     System.out.println(singleton1 == singleton2 ? "Objects are equal" : "Objects are different");

              } catch (ClassNotFoundException | InstantiationException

                           | IllegalAccessException | IllegalArgumentException

                           | InvocationTargetException | NoSuchMethodException

                            | SecurityException e) {

                     e.printStackTrace();

              }

       }

}

 

  1. A) In that case I can implement Singleton like below for not to be broken with reflection

class Singleton {

       private static Singleton INSTANCE;

       private Singleton() {

              if (INSTANCE != null)

                     throw new RuntimeException(

                                  "Singleton can not be created more than once.");

       }

       public static Singleton getInstance() {

              if (INSTANCE == null) {

                     synchronized (Singleton.class) {

                           if (INSTANCE == null) {

                                  INSTANCE = new Singleton();

                           }

                     }

              }

              return INSTANCE;

       }

}

 

Private constructor will be called to instantiate the Singleton object through reflection. So we can throw some exception If INSTANCE field is not null (that means its already created).

 

  1. Q) So you think this implementation saves your Singleton from being broken from reflection. In my previous program, I am trying to create a Singleton object (singleton1) with the help of getInstance() and after that trying to create another object (singleton2) with the help of reflection. What happens If I do this in reverse like below

 

public class Test {

       public static void main(String args[]) {

//            Singleton singleton1 = Singleton.getInstance();

              Singleton singleton2 = null;

              try {

                     // Test is package name contains Singleton class

                     Class singletonClass = Class.forName("Test.Singleton");

                     // as we know there is only one private constructor

                     Constructor cons = singletonClass.getDeclaredConstructor();

                     cons.setAccessible(true);

                     singleton2 = (Singleton) cons.newInstance();

                     Singleton singleton1 = Singleton.getInstance();

                     System.out.println(singleton1 == singleton2 ? "Objects are equal" : "Objects are different");

              } catch (ClassNotFoundException | InstantiationException

                            | IllegalAccessException | IllegalArgumentException

                           | InvocationTargetException | NoSuchMethodException

                           | SecurityException e) {

                     e.printStackTrace();

              }

       }

}

 

Output:

 Objects are different

 

Here, If I try to create a Singleton object (singleton2) with the help of reflection first then it can proceed to create an Singleton object as the static field INSTANCE is still null at that time as getInstance() is not yet invoked. So we are allowed to create an many as objects we want for the Singleton using reflection before getInstance() is invoked and thus breaks the singleton. What do you say?

 

  1. A) Yeah, you are right. Let me come to you with slightly modified implementation of Singleton which protects itself from being broken with reflection.

 

class Singleton {

       private static Singleton INSTANCE;

       private static boolean instanceCreated = false;

       private Singleton() {

          &

0 Dislike
Follow 0

Please Enter a comment

Submit

Other Lessons for You

Overloading in JAVA
When a class contains more than one method with the same method name but different argument types, then it is called Overloading. Methods are said to be Overloaded methods. Also, know as Compile time...

Fractional Knapsack
Algorithm - Fractional Knapsack import java.util.Scanner; public class Knapsack01 { public static void main(String args) { Scanner scan = new Scanner(System.in); int...

Class and Objects in Java
Class is a template or a blueprint which is used to describe an object. On other hand Object is a reference of a class which follows all the stuff written inside the class. How about taking the whole tour in the following video

ClassNotFoundException vs NoClassDefFoundError
ClassNotFoundException NoClassDefFoundError It is an exception and happens due to programmer’s mistake and can be recovered by updating the code. Thrown when an application tries...

Comparable vs Comparator
java.lang.Comparable java.util.Comparator For comparing some other object with its own object. Ex. I am comparing myself to some other employee. Method signature is: int compareTo (T object). For...
X

Looking for Java Training Classes?

The best tutors for Java Training Classes are on UrbanPro

  • Select the best Tutor
  • Book & Attend a Free Demo
  • Pay and start Learning

Learn Java Training with the Best Tutors

The best Tutors for Java Training Classes are on UrbanPro

This website uses cookies

We use cookies to improve user experience. Choose what cookies you allow us to use. You can read more about our Cookie Policy in our Privacy Policy

Accept All
Decline All

UrbanPro.com is India's largest network of most trusted tutors and institutes. Over 55 lakh students rely on UrbanPro.com, to fulfill their learning requirements across 1,000+ categories. Using UrbanPro.com, parents, and students can compare multiple Tutors and Institutes and choose the one that best suits their requirements. More than 7.5 lakh verified Tutors and Institutes are helping millions of students every day and growing their tutoring business on UrbanPro.com. Whether you are looking for a tutor to learn mathematics, a German language trainer to brush up your German language skills or an institute to upgrade your IT skills, we have got the best selection of Tutors and Training Institutes for you. Read more