Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

singleton pattern in java. lazy initialization

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

1.is there a flaw with the above implementation of the getInstance method? 2.What is the difference between the two implementations.?

public static synchronized MySingleton getInstance() { 
 if (_instance==null) {
  _instance = new MySingleton();
 }

 return _instance;
} 

I have seen a lot of answers on the singleton pattern in stackoverflow but the question I have posted is to know mainly difference of 'synchronize' at method and block level in this particular case.

like image 762
flash Avatar asked Mar 26 '10 08:03

flash


2 Answers

1.is there a flaw with the above implementation of the getInstance method?

It does not work. You can end up with several instances of your Singleton.

2.What is the difference between the two implementations.?

The second one works, but requires synchronization, which could slow down the system when you have a lot of accesses to the method from different threads.

The most straightforward correct implementation:

public class MySingleton{
    private static final MySingleton _instance = new MySingleton();
    private MySingleton(){}
    public static MySingleton getInstance() { 
        return _instance;
    }
}

Shorter and better (safely serializable):

public enum MySingleton{
    INSTANCE;

    // methods go here
}

Lazy initialization of singletons is a topic that gets attention way out of proportion with its actual practical usefulness (IMO arguing about the intricacies of double-checked locking, to which your example is the first step, is nothing but a pissing contest).

In 99% of all cases, you don't need lazy initialization at all, or the "init when class is first referred" of Java is good enough. In the remaining 1% of cases, this is the best solution:

public enum MySingleton{
    private MySingleton(){}
    private static class Holder {
         static final MySingleton instance = new MySingleton();
    }
    static MySingleton getInstance() { return Holder.instance; }
}

See Initialization-on-demand holder idiom

like image 113
Michael Borgwardt Avatar answered Oct 05 '22 05:10

Michael Borgwardt


1.is there a flaw with the above implementation of the getInstance method?

Yes, the synchronized keyword should wrap the if statement as well. If it's not then two or more threads could potentially get through to the creation code.

2.What is the difference between the two implementations.?

The second implementation is correct and from my point of view easier to understand.

Using synchronized at the method level for a static method synchronizes on the class, i.e. what you've done in sample 1. Using synchronized at the method level for an instance method synchronizes on the object instance.

like image 23
Adrian Avatar answered Oct 05 '22 05:10

Adrian