views:

448

answers:

9

Hi ,

I was refering to a solution from wikipedia for Singleton Pattern:

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;
   }

}

This can be found at http://en.wikipedia.org/wiki/Singleton_pattern under The solution of Bill Pugh

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, isnt there a possibility that 2 threads would call getInstance() method at the same time which would lead to two instaces of singleton being created . Isnt it safe to use synchronized here. If Yes, where should it be used in the code.

Thanks

A: 

The singleton is created in a static initialization block, before any getInstance() method is called.

GregS
The static initializer belongs to the inner class, and as such it is not executed until getInstance() is called.
danben
+8  A: 

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.
ZoogieZork
+3  A: 

Here is the explanation from Wikipedia on this phenomenon (emphasis mine):

When the class Something is loaded by the JVM, the class goes through initialization. Since the class does not have any static variables to initialize, the initialization completes trivially. The static class definition LazyHolder within it is not initialized until the JVM determines that LazyHolder must be executed. The static class LazyHolder is only executed when the static method getInstance is invoked on the class Something, and the first time this happens the JVM will load and initialize the LazyHolder class. The initialization of the LazyHolder class results in static variable something being initialized by executing the (private) constructor for the outer class Something. Since the class initialization phase is guaranteed by the JLS to be serial, i.e., non-concurrent, no further synchronization is required in the static getInstance method during loading and initialization. And since the initialization phase writes the static variable something in a serial operation, all subsequent concurrent invocations of the getInstance will return the same correctly initialized something without incurring any additional synchronization overhead.

So in your example, Singleton is "LazyHolder" and SingletonHolder is "Something". Calling getInstance() twice will not cause a race condition due to the JLS guarantees.

danben
+4  A: 

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

Gregory Pakosz
A: 

I think the idea is that Java guarantees that a class can only be initialized once, so implicitly only the first thread to access would cause this to happen

alasdairg
A: 

The Singleton is created when Singleton.getInstance() is called at this time the INSTANCE will be instantiated. Synchronization depends on a conrete implementation, since there are no values to modify (in this example) no synchronization is required.

stacker
A: 

There are two differences here that need to be noted. The first is the Singleton design pattern and the other is a singleton instance.

The Singleton design pattern is problematic due to the fact that the design pattern represents a singleton instance as is implemented using static state (which is a bad thing for a variety of reasons - especially with unit testing). The second is an instance for which there is only one instance, no matter what (like the JVM singleton implemented as an enum).

The enum version is definitely superior, when compared to the Singleton pattern.

If you don't want to implement all instances as enum instances, then you should think about using Dependency Injection (frameworks such as Google Guice) to manage the singleton instances for the application.

gpampara
A: 

This idiom is known as the Initialization on Demand Holder (IODH) idiom and is discussed in Item 48 of Effective Java as reminded by Bob Lee in his great post about Lazy Loading Singletons:

Item 48: Synchronize access to shared mutable data

(...)

The initialize-on-demand holder class idiom is appropriate for use when a static field is expensive to initialize and may not be needed, but will be used intensively if it is needed. This idiom is shown below:

// The initialize-on-demand holder class idiom
private static class FooHolder {
     static final Foo foo = new Foo();
}
public static Foo getFoo() { return FooHolder.foo; }

The idiom takes advantage of the guarantee that a class will not be initialized until it is used [JLS, 12.4.1]. When the getFoo method is invoked for the first time, it reads the field FooHolder.foo, causing the FooHolder class to get initialized. The beauty of this idiom is that the getFoo method is not synchronized and performs only a field access, so lazy initialization adds practically nothing to the cost of access. The only shortcoming of the idiom is that it does not work for instance fields, only for static fields.

However, in the Second Edition of Effective Java, Joshua explains how enums can be (ab)used for writing a serializable Singleton (this should be the preferred way with Java 5):

As of release 1.5, there is a third approach to implementing singletons. Simply make an enum type with one element:

// Enum singleton - the preferred approach
public enum Elvis {
     INSTANCE;
     public void leaveTheBuilding() { ... }
}

This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.

Pascal Thivent
A: 

So the crux of the answer is in Java => a class will not be initialized until it is used.

Is it true only about static class ? or static members of the class for that matter ?

p1