Javaコンカレント:スレッドセキュリティの単一モード


転載は出典を明記してください:jiq・欽'stechnical Blog
1、餓漢式
public class Singleton {
  private final static Singleton INSTANCE = new Singleton();
  private Singleton() { }
  public static Singleton getInstance() {
     return INSTANCE;
   }
} 

欠点:クラスがロードされるとスペースが割り当てられ、使用しないとメモリ領域が消費されます.
2、怠け者
2.1通常ロックモード
public class Singleton {
  private static Singleton instance = null;
  private Singleton() { }
 
  public static synchronized Singleton getInstance() {
     if(instance == null) {
        instance = new Singleton();
     }
     return instance;
   }
} 

欠点:各スレッド呼び出しgetInstanceはロックされ、効率が低く、getInstanceが初めて呼び出されたときにのみロックされたい場合は、次の二重検出スキームを参照してください.
2.2プレースホルダモード(推奨)
Javaメカニズムでは、内部クラスSingletonHolderはgetInstance()メソッドが最初に呼び出されたときにのみロードされ(lazyが実現される)、そのロードプロセスはスレッドが安全であることが規定されているため、怠け者式の単一例に属する.内部クラスがロードされるとinstanceがインスタンス化されます.
public class Singleton {
  private Singleton() { }
   privatestatic class SingletonHolder {  
//   ,         ,   SingletonHolder    
//    :static              , JVM  
     static Singleton INSTANCE = new Singleton();
   }
  public static Singleton getInstance() {
     return SingletonHolder.INSTANCE;
   }
}

2.3二重検査
通常の二重検査:
public class Singleton {
  private static Singleton instance = null;
  private Singleton() { }
  public static Singleton getInstance() {
     if(instance == null) {
        synchronzied(Singleton.class) {
           if(instance == null) {
               instance = new Singleton();
           }
        }
     }
     return instance;
   }
}

欠点:命令の並べ替え問題、私のこの文章を参考にします
.
ソリューション:
instanceインスタンス変数に対してvolatileで修飾すればよいが,volatileで修飾すればinstance=new Singleton()を確保できる.対応する命令は並べ替えられません.
public class Singleton {
  private static volatile Singletoninstance = null;  // volatile           
  private Singleton() { }  //       ,      
  public static Singleton getInstance() {
     if(instance == null) {     //    
        synchronzied(Singleton.class) {
           if(instance == null) {
               instance = new Singleton();
           }
        }
     }
     return instance;
   }
}