<

Go Premium for a chance to win a PS4. Enter to Win

x

Use Lazy Initialization in singleton pattern

Published on
15,899 Points
4,999 Views
9 Endorsements
Last Modified:
Awarded
An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing instance is used.
public class MySingletonClass {
    private static MySingletonClass instance; 

    private MySingletonClass(){
      //private constructor to prevent extra instantiation
    }

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

    // rest of MySingletonClass's methods... 
}

Open in new window


However, this approach has the potential of not working in multi-threaded programs. If two different threads simultaneously invoke your method (i.e., getInstance()), they would most likely create two different instances while you expected that object to create only once across your application. Another method to evade this problem is "double-checked locking", which is rejected now and won't work properly as well.

Here is an example of the double-checked locking method for your reference:
public class MySingletonClass {
    private static MySingletonClass instance; 

    private MySingletonClass(){
      //private constructor to prevent extra instantiation
    }

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

    // rest of MySingletonClass's methods... 
}

Open in new window



Fortunately, this article will show you how to get around this problem using the following steps:

1. Define a static inner class


First define a static inner class and make it private. For example LazyInitializer, and then put the "instance" field into it. Then you have to initialize the instance in declaration.
//Lazy initializing method
public class MySingletonClass { 
    private static class LazyInitializer {
        private static MySingletonClass instance = new MySingletonClass();
    }
}

Open in new window


2. Create getInstance() method


Now create the instance method as below:
public static MySingletonClass getInstance(){
   return LazyInitializer.instance;
}

Open in new window


3. If your instance needs to be initialized


In this case use a static block inside the inner class:

public class MySingletonClass {
     
    private static class LazyInitializer{
         private static MySingletonClass instance = new MySingletonClass();
         static {
             instance.setMyParam("A_PARAM_VALUE");
         }
    } 
}

Open in new window


4. Put it altogether


This is the whole snippet:
//Lazy initializing method
public class MySingletonClass {
 
    private MySingletonClass(){
      //private constructor to prevent extra instantiation
    } 
    private static LazyInitializer {
         private static MySingletonClass instance = new MySingletonClass();
    } 
    public static MySingletonClass getInstance(){
        return LazyInitializer.instance;
    }
    // rest of MySingletonClass's methods... 
}

Open in new window



Editor's Note: for those new to Java programming or to using design patterns such as Singletons, I can atest to the frequency in which I personally use this construct. Consequently, with the increasing need for concurrency in applications, I strongly recommend you internalize the above information and any additional research you may need to fully grasp the concept. Therefore, this is short and sweet, but great knowledge as you embark as a Java developer!
9
Comment
Author:mnrz
6 Comments
 
LVL 60

Expert Comment

by:Kevin Cross
Kudos, mnrz.
Voted yes above.
0
 
LVL 8

Expert Comment

by:WhiteMage
I think you forgot "class" in "private static class LazyInitializer", just for anyone new out there reading this.

Good read.  However, i was thinking will LazyInitializer.instance always be created?  Wonder if for some reason you didn't want the instance to be created until getInstance is called for the first time to save memory or something.  Although, I can't really think of a reason why you'd want to do this.  Why would you import a class that you don't use or have an empty instance lying around?  I guess this way is really the only way though to prevent multiple thread problems like you said.
0
 
LVL 8

Author Comment

by:mnrz
Thank you so much mwvisa1

to WhiteMage, yes you're right a 'class' is missed there sorry for that and thank you to comment it
Why we use this, because recent machines have more than one CPU. I am not very expert in this area but as far as I know these multi-cpu machines have many feature for better performance so guys who developed new JVMs (since version 5 I think) have changed the memory management in order to use the most of it. In this way the old-fashioned singleton patterns won't work! Maybe you have no problem with your personal computer even with hundred threads but in a server machine you will. I had this experience once and I was wondered how this singleton turn out to two instances!!!

Regarding the unwanted instance I guess (not sure but I read somewhere a long time ago) that since this is an inner class so JVM will not load it unless a first access to it

   
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 3

Expert Comment

by:grouper15
Hi mnrz

I just wanted to discuss is it only the object creation (lazy initialization) that drives you to make inner class and put the singleton instance in it. I mean what if we have the following code

public class MySingletonClass {
    private static MySingletonClass instance = new MySingletonClass();

    private MySingletonClass(){
      //private constructor to prevent extra instantiation
    }

    public static MySingletonClass getInstance(){        
        return instance;
    }

    // rest of MySingletonClass's methods...
}


Now i know that here the singleton instance will be created alongwith the class being loaded. But there wont be any multithreaded issues. right

So can i say that if i need my singleton instance at some delayed point in time then i can use your version and if its instantly needed (at first reference of the class) then i can use above ?
0
 
LVL 8

Author Comment

by:mnrz
Yes you're right. The sample you gave has no problem with multi-threading issue. But sometimes you need to initialize the 'instance' along with creation. In this case, You may need a static block.

The main reason for lazy initialization is that this instance may not be used for a long time, so it's better not to load it until then
0
 
LVL 1

Expert Comment

by:Shura85
Thanks mnrz - great article.  I'm using Singletons a lot these days, and this is a new approach to the synchronization issues I'm facing.  
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Join & Write a Comment

Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
Suggested Courses

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month