11

I have 2 options:

  1. Singleton Pattern

    class Singleton{
        private static Singleton singleton = null;
    
        public static synchronized Singleton getInstance(){
            if(singleton  == null){
                singleton = new Singleton();
            }
            return singleton;
        }
    }
    
  2. using a static final field

    private static final Singleton singleton = new Singleton();
    
    public static Singleton getSingleton() {
        return singleton;
    }
    

Whats the difference? (singlethreaded or multithreaded)

Updates: I am aware of Bill Pugh or enum method. I am not looking for the correct way, but I have only used 1. Is there really any difference b/w 1 or 2?

David Foerster
  • 1,461
  • 1
  • 14
  • 23
Achow
  • 8,600
  • 6
  • 39
  • 49
  • After your updated question no difference. – Bhavik Ambani Dec 05 '12 at 13:26
  • 1
    this question is nothing to do with singleton. you ask about accessing a static field from synchronized/non-synchronized context. edit tags please. – Juvanis Dec 05 '12 at 13:26
  • @BhavikAmbani I disagree as the first option will lock each thread that attempts to get the instance and is therefore slightly less performant. – John B Dec 05 '12 at 13:28
  • 1
    @anirbanchowdhury its not good practice to use `synchronized` an all your method. `synchronized` implementation is very expensive. I posted under other better way to use Singleton for multithreading – Maxim Shoustin Dec 05 '12 at 13:35

4 Answers4

10

The main difference is that with the first option , the singleton will only be initialised when getInstance is called, whereas with the second option, it will get initialized as soon as the containing class is loaded.

A third (preferred) option which is lazy and thread safe is to use an enum:

public enum Singleton {
    INSTANCE;
}
assylias
  • 321,522
  • 82
  • 660
  • 783
  • My mistake ,somehow missed it. Have updated the question now. Also, I am aware of the ENUM singleton instance, just wanted to know the difference b.w the 2, but thanks anyways! – Achow Dec 05 '12 at 13:24
3

There is one difference:

Solution 1 is a lazy initialization, the singleton instance will be created on the first invoke of getInstance

Solution 2 is a eager initialization, the singleton instance will be create when the class loades

They both are thread safe, calling the second one multi threaded is a little misleading

Aviram Segal
  • 10,962
  • 3
  • 39
  • 52
2

The 1st solutions appears to be lazier, but actually not.

A class is initialized when a static method/field is accessed for the 1st time.

It's likely that getInstance() is the only publicly accessible static method/field of the class. That's the point of singleton.

Then the class is initialized when someone calls getInstance() for the 1st time. That means the two solutions are essentially the same in laziness.

Of course, the 2nd solutions looks better and performs better.

irreputable
  • 44,725
  • 9
  • 65
  • 93
  • Lazy being, no instance of Singleton being created till getInstance() is explicitly invoked. The class will obviously be loaded both times. Or am I missing something? – Achow Dec 11 '12 at 07:49
  • 1
    in the 2nd solution, the instance is only created when the class is initialized; the class is initialized only when a static method/field is accessed, i.e., when getInstance() is invoked. – irreputable Dec 11 '12 at 13:48
1

So, with the update both options above are thread-safe. However the synchronized option requires each thread that calls instance to acquire this lock thereby reducing performance if this is done a lot. Also, using synchronized at the method level has the potential issue of using a publicly available lock (the class itself) that therefore if some thread acquires this lock (which it could) you could end up with deadlock. The static final option is more performant but does not do lazy initialization of the singleton (which might not be an issue depending on the system).

Another option that allows thread-safe lazy init of the Singleton is as follows:

 public class MySingleton{
      private static class Builder{
          private static final MySingleton instance = new MySingleton();
      }

      public static MySingleton instance(){
           return Builder.intance;
      }
 }

This works because the static inner class is guarenteed to be initialized before any method in the containing class is executed.

cHao
  • 84,970
  • 20
  • 145
  • 172
John B
  • 32,493
  • 6
  • 77
  • 98
  • I just reread the answer, and it doesn't have the problem i thought it had. Sorry bout that. :) Removed my -1. The answer does look a bit like word salad to me, though...and just barely touches on the real difference (lazy vs eager initialization). You mention performance and locking, but those are not the main difference. – cHao Dec 05 '12 at 15:17