需要Java Singleton解释

sur*_*a2k 2 java singleton thread-safety

通常我使用第一个实现.几天前我发现了另一个.任何人都可以解释这两个实现之间的区别吗?第二个实现是线程安全的吗?在第二个例子中使用内部类有什么好处?

//--1st Impl
public class Singleton{

      private static Singleton _INSTANCE;

      private Singleton() {}
      public static Singleton getInstance(){
          if(_INSTANCE == null){
               synchronized(Singleton.class){
                      if(_INSTANCE == null){
                          _INSTANCE = new Singleton();
                      }
               }
          }
      return _INSTANCE;
      }  
}

//--2nd Impl
public class Singleton {
      private Singleton() {}

      private static class SingletonHolder { 
            private static final Singleton _INSTANCE = new Singleton();
      }

      public static Singleton getInstance() {
            return SingletonHolder._INSTANCE;
      }
}
Run Code Online (Sandbox Code Playgroud)

Cam*_*ner 7

第一个实现使用所谓的"双重检查锁".这是一件非常糟糕的事情.它看起来是线程安全的,但事实上并非如此.

第二种实现确实是线程安全的.

第一个实现被破坏的原因相当复杂,因此我建议您获取Brian Goetz的Java Concurrency in Practice的副本,以获得详细说明.简短版本是允许编译器_INSTANCE在构造函数完成之前分配变量,这可能导致第二个线程看到部分构造的对象.