同時プログラミング実戦3-単例モードとスレッドセキュリティの問題


シングル・インスタンス・モードは、1つのアプリケーションにインスタンス・オブジェクトが1つしかないことを保証するため、シングル・スレッドの場合は構造方法をプライベート化し、オブジェクトの一意指定を加えるだけで実現できますが、マルチスレッドの場合は問題が発生します
  • 命令再ソート:
  • 現代のマイクロプロセッサの多くは、命令を乱順に実行することを採用しています.(out-of-order execution、OoOEまたはOOEと略称する)の方法では、条件が許す限り、現在すぐに実行できる後続命令を直接実行し、次の命令に必要なデータを取得する際の待機3を避ける.乱順実行の技術により、プロセッサは実行効率を大幅に向上させることができる.
  • すなわち、データの切り替え取得を低減するために、単一スレッドプログラムの論理に影響を及ぼさない前提で、プロセッサは同じリソースの命令を一緒に実行し、中間の順序を乱す.したがって、newオブジェクトがまだ存在しないと同時に(2)、オブジェクトアドレス(3)が制定されている.すなわち、順序は132である.

  • 単例パターンの分類:*餓漢式*餓漢式は初期化時にオブジェクトが生成されるため安全上の問題はない
    ``` stylus
    /**
     * @author: ZouTai
     * @date: 2018/4/8
     * @description:    :     (      )
     */
    public class Singleton {
        /**
         * 1、      
         */
        private Singleton(){}
    
        /**
         * 2、      ,  
         */
        public static Singleton singleton = new Singleton();
    
        public Singleton getInstance() {
            return singleton;
        }
    }
    ```
    
  • 怠け者式
  • 怠け者式は、オブジェクトを初期化するときに使用され、複数のスレッドがアクセスすると、スレッドセキュリティの問題が発生します.
        /**
     * @author: ZouTai
     * @date: 2018/4/8
     * @description:    :      ,         (     )
     */
    public class Singleton2 {
        private Singleton2() {
        }
    
        private static Singleton2 singleton = null;
    
        /**
         *       -        
         *    -》    -》    
         *
         * @return
         */
        public static Singleton2 getInstance() {
            //  =while(true)  cpu
            if (singleton == null) { //        
                synchronized (Singleton2.class) {
                    //        ,              
                    if (singleton == null) {
                        singleton = new Singleton2();//      
    
                    //            // 1
                    //              // 2
                    // instance              // 3
                    }
                }
            }
            return singleton;
        }
    }