Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton pattern implementation from Wikipedia

I am referring to the solution for the Singleton Pattern by Bill Pugh on Wikipedia:

public class Singleton
{

    // Private constructor prevents instantiation from other classes

    private Singleton() {}

     /**
    * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
    * or the first access to SingletonHolder.INSTANCE, not before.
    */

    private static class SingletonHolder 
    { 

        private static final Singleton INSTANCE = new Singleton();
    }

   public static Singleton getInstance()
   {

       return SingletonHolder.INSTANCE;
   }

}

Here they have mentioned:

The inner class is referenced no earlier (and therefore loaded no earlier by the class loader) than the moment that getInstance() is called. Thus, this solution is thread-safe without requiring special language constructs (i.e. volatile or synchronized).

However, isn't there a possibility that 2 threads would call getInstance() at the same time, which would lead to two instances of singleton being created? Isn't it safe to use synchronized here? If yes, where should it be used in the code?

like image 675
p1. Avatar asked Jan 10 '10 17:01

p1.


2 Answers

See the "How it works", in the article "Initialization on demand holder idiom" linked from the same section.

In a nutshell, here's what happens when you call getInstance() the first time:

  1. The JVM sees a reference to SingletonHolder it has never seen referenced before.
  2. Execution is paused while it initializes SingletonHolder. This includes running any static initialization, which includes the singleton instance.
  3. Execution resumes. Any other threads calling getInstance() at the same time will see that SingletonHolder is already initialized. The Java spec guarantees that class initialization is thread-safe.
like image 126
ZoogieZork Avatar answered Sep 19 '22 02:09

ZoogieZork


The JLS guarantees the JVM will not initialize instance until someone calls getInstance(); and that will be thread safe because it would happen during the class initialization of SingletonHolder.

However, since Java 5, the preferred approach involves Enum:

// Enum singleton - the preferred approach
public enum Elvis {
    INSTANCE;

    public void leaveTheBuilding() { ... }
}

Reference: Implementing the singleton pattern in Java

like image 24
Gregory Pakosz Avatar answered Sep 21 '22 02:09

Gregory Pakosz