Singleton lazy vs eager instantiation
Asked Answered
P

5

40

If a singleton is implemented as follows,

class Singleton {
    private static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }
}

How is this implementation different from the lazy initialization approach? In this case,the instance will be created when the class is loaded and the class itself is loaded only on the first active use (for example, Singleton.getInstance() not when you declare for instance Singleton singleton = null;)

Even with lazy initialization approach, the instance is created on the call to getInstance()

Am i missing something here?

Propensity answered 17/10, 2011 at 6:39 Comment(4)
You have missed the point. You may call any other static methods too.Initialization on demand holder idiom fix this problem.Storytelling
Take a look at this csharpindepth.com/Articles/General/Singleton.aspx It s c# , but it might help you.Unravel
Prince, I think you have answered my question. ThanksPropensity
@Propensity it would be nice to see a comparison of the two methods to provide further context on the question. (Friendly suggestion).Ursula
S
19

You may call any other static methods or static member variable too to load the singleton instance.

class Logger {     
   private static Logger instance = new Logger(); 
   public static String LOG_LINE_SEPERATOR =  
      System.getProperty("line.separator");
   public static Logger getInstance() {  
          return instance;     
   } 

   public static String logPattern() {
       return null;
   }
} 

...

Logger.LOG_LINE_SEPERATOR; // load Logger instance or
Logger.logPattern(); // load Logger instance
Storytelling answered 17/10, 2011 at 7:0 Comment(2)
@Prince.I did not understand how it answer the given question.We can call other static methods in lazy initialisation also as we dont need instance for that.And we can do class.method().How did lazy vs eager initialization helps here?What did i miss?Izettaizhevsk
@rahulsharma I think what Prince is trying to say is: 1) The singleton might have other methods. 2) with eager initialisation, even if you were to call one of these other methods, your Singleton instance ends up getting initialised. This is due to how JVM is defined. docs.oracle.com/javase/specs/jls/se7/html/… 3) But with lazy initialisation, If you were to call one of the other methods, The static singleton instance will not end up getting initialised. Atleast that what I undrestood from his msg. not sure tho. If someone can confirm, it would be great.Samurai
E
28

With lazy initialization you crate instance only when its needed and not when the class is loaded. So you escape the unnecessary object creation. That being said there are other things to consider too. In lazy initialization you give a public API to get the instance. In multi-threaded environment it poses challenges to avoid unnecessary object creation. you put synchronization blocks which poses unnecessary locking to be done to check for object already created. So it becomes a performance issue in this case.

So if you are sure that creating you object is not going to take any significant memory and its almost always going to be used in your application then its good to create in static initialization. Also please do not forget to make your instance final in this case as it make sures that the object creation is reflected properly and in totality to main memory which is important in multi-threaded environment.

Please refer this tutorial from IBM on Singleton+ Lazy Loading+ Multithreaded Environment case

===============Edit on 09/09/2018====================

You should also look at object creation on demand pattern here.

Emaemaciate answered 17/10, 2011 at 6:51 Comment(0)
S
19

You may call any other static methods or static member variable too to load the singleton instance.

class Logger {     
   private static Logger instance = new Logger(); 
   public static String LOG_LINE_SEPERATOR =  
      System.getProperty("line.separator");
   public static Logger getInstance() {  
          return instance;     
   } 

   public static String logPattern() {
       return null;
   }
} 

...

Logger.LOG_LINE_SEPERATOR; // load Logger instance or
Logger.logPattern(); // load Logger instance
Storytelling answered 17/10, 2011 at 7:0 Comment(2)
@Prince.I did not understand how it answer the given question.We can call other static methods in lazy initialisation also as we dont need instance for that.And we can do class.method().How did lazy vs eager initialization helps here?What did i miss?Izettaizhevsk
@rahulsharma I think what Prince is trying to say is: 1) The singleton might have other methods. 2) with eager initialisation, even if you were to call one of these other methods, your Singleton instance ends up getting initialised. This is due to how JVM is defined. docs.oracle.com/javase/specs/jls/se7/html/… 3) But with lazy initialisation, If you were to call one of the other methods, The static singleton instance will not end up getting initialised. Atleast that what I undrestood from his msg. not sure tho. If someone can confirm, it would be great.Samurai
E
8

For the reasons you mention, this is just a more complicated way of doing much the same as

enum Singleton {
    INSTANCE;
}

Using lazy initialisation is only useful if you are concerned that the class could be initilised but you don't want to load the singleton at that point. For most situations this is over kill.

Note: Just referencing the class does not initialise the class.

e.g. Say you have a badly written class which cannot be initilised until some condition is set. In this case n must be non-zero.

public class Main {
    public static void main(String ... args) {
        Class c= LazyLoaded.class;
        System.out.println(c);
    }

    static class LazyLoaded {
        static int n = 0;
        static {
            System.out.println("Inverse "+1000/n);
        }
    }
}

prints

class Main$LazyLoaded
Entero answered 17/10, 2011 at 7:47 Comment(1)
Why is it called lazy?Epiphany
S
1

First of all, the singleton pattern is overused. What you really want to do if you want "one of something" is to declare it a singleton in your DI framework of choice. This is effectively a configuration driven eager singleton, and frees up options for injecting mocks to do proper testing.

Why not lazy load? Unless your class has a massive initialization routine in construction (which I would argue is also an anti-pattern), there is no benefit and lots of drawbacks to lazy loading. You're just adding complexity and possibly breaking your program if it's not done correctly. The correct way (if you must) is to use the Initialization-on-demand holder idiom.

Subsistent answered 19/10, 2017 at 19:2 Comment(0)
C
0

For lazy loading singleton instance, I am using as below.

class Singleton {
private static Singleton instance;
private Singleton(){

}
public static Singleton getInstance() {
    if(null==instance){
        synchronized(Singleton.class){
            if(null==instance){
                instance = new Singleton();
            }
        }
    }
    return instance;
}
}
Cheerless answered 4/1, 2018 at 7:46 Comment(2)
instance is always null. You should initialize it in the if block. Still, this isn't thread-safe.Distend
The instance field must be volatile, otherwise this can create duplicate instances. See double-checked locking in Java.Righthander

© 2022 - 2024 — McMap. All rights reserved.