The Java programming language solutions provided here are all thread-safe but differ in supported language versions and lazy-loading.

The solution of Bill Pugh
This is the recommended method. It is known as the initialization on demand holder idiom and is as lazy as possible. Moreover, it works in all known versions of Java. This solution is the most portable across different Java compilers and virtual machines.

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 and/or synchronized).

public class Singleton {
   // Private constructor suppresses generation of a (public) default constructor
   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 final static Singleton instance = new Singleton();
   }
 
   public static Singleton getInstance() {
     return SingletonHolder.instance;
   }
 }

Traditional simple way
Just like the one above, this solution is thread-safe without requiring special language constructs, but it lacks the laziness. The INSTANCE is created as soon as the Singleton class loads. That might even be long before getInstance() is called. It might be (for example) when some static method of the class is used. If laziness doesn't bother you or you need the instance to be created early in your application's execution, you can use this (slightly) simpler solution:

public class Singleton {
   private final static Singleton instance = new Singleton();
 
   // Private constructor suppresses generation of a (public) default constructor
   private Singleton() {}
 
   public static Singleton getInstance() {
     return instance;
   }
 }

Java 5 solution
If and only if your compiler is Java 5 (also known as Java 1.5) or newer, AND all Java virtual machines your application is going to run on fully support the Java 5 memory model, then (and only then) you can use volatile double checked locking (for a detailed discussion of why you should never do this before Java 5 see The "Double-Checked Locking is Broken" Declaration):

public class Singleton {
   private static volatile Singleton INSTANCE;
 
   // Private constructor suppresses generation of a (public) default constructor
   private Singleton() {}
 
   public static Singleton getInstance() {
     if (INSTANCE == null)
       synchronized(Singleton.class) {
         if (INSTANCE == null)
           INSTANCE = new Singleton();
       }
     return INSTANCE;
   }
 }

Allen Holub (in "Taming Java Threads", Berkeley, CA: Apress, 2000, pp. 176-178) notes that on multi-CPU systems (which are widespread as of 2007), the use of volatile may have an impact on performance approaching to that of synchronization, and raises the possibility of other problems. Thus this solution has little to recommend it over Pugh's solution described above.

Reference:
http://en.wikipedia.org/wiki/Singleton_pattern

Posted by 알 수 없는 사용자
,