面接シリーズの単例モード

3053 ワード

一、単例モード
単例モードは最もよく使われる設計モードの一つで、面接で面接官に手書きを要求されることが多い.
1、単例モードとは
クラスにインスタンスが1つしかないことを保証し、そのグローバル・アクセス・ポイントにアクセスします.たとえば、システムの起動時に共通の構成情報をロードする必要があります.アプリケーション全体のライフサイクルで表示され、一意である場合は、単一のモードに設計する必要があります.たとえば、springコンテナ、sessionファクトリ、キャッシュ、データベース接続プールなどです.
2、インスタンスの一意性を保証する方法
         
       
           
    

二、単例モードのJava実現
単例モードの実現方式の良し悪しを測定する3つの基準:怠惰なロード、スレッドの安全、効率が高い.
1、餓漢式
「お腹が空いているので待つことはできません」は、クラスの静的プライベート変数を定義しながらインスタンス化します.
    public class Singleton {
        private static final Singleton singleton = new Singleton();
        private Singleton() {
        }
        public static Singleton getInstance() {
            return singleton;
        }
    }

利点:簡単で、クラスのロード時にインスタンス化を完了し、スレッドの同期問題を回避します.スレッドは安全です.欠点:lazy loadingの効果がありません;
クラスインスタンス化のプロセスを静的コードブロックに配置することもできます.効果は同じです.
2、怠け者
「怠け者で、使うときにインスタンス化する」と、ロードが遅延します.キーワードsynchronizedの使用とは異なり、怠け者式とスレッドセキュリティに分けられる怠け者式です.
    public class Singleton {
        private static Singleton singleton = null;
        private Singleton() {
        }
        public synchronized static Singleton getInstance() {
            if (singleton == null) {
                singleton = new Singleton();
            }
            return singleton;
        }
    }

利点:怠け者で、スレッドが安全です.欠点:インスタンスを取得するたびにロックをかけ、リソースを消費しますが、インスタンスが生成されている限り、後でロックする必要はありません.
3、二重検査錠
    public class Singleton {
        private static Singleton singleton;
        private Singleton() {
        }
        public static Singleton getInstance() {
            if (singleton == null) {
                synchronized (Singleton.class) {
                    if (singleton == null) {
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }

利点:怠惰なロード;スレッドセキュリティ;インスタンスが初期化されない前に同期するだけで効率が高いことを保証するために、二重チェックを行います.
4、静的内部クラス
静的内部クラス方式Singletonクラスがマウントされるとすぐにインスタンス化するのではなく、インスタンス化が必要な場合にgetInstanceメソッドを呼び出してSingletonHolderクラスをマウントし、Singletonのインスタンス化を完了し、怠惰なロードを実現する.クラスの静的プロパティは、クラスが最初にロードされたときにのみ初期化されるため、ここではJVMがスレッドのセキュリティを保証し、クラスが初期化されたときに他のスレッドはアクセスできません.
    public class Singleton {
        private Singleton() {
        }
        private static class SingletonHolder {
            private static final Singleton singleton = new Singleton();
        }
        public static Singleton getInstance() {
            return SingletonHolder.singleton;
        }

    }

利点:怠惰なロード;スレッドセキュリティ;同時に同期による性能損失を回避し、効率が高い.
5、列挙
    public enum Singleton{
        INSTANCE;
        public void otherMethods(){
            System.out.println("Something");
        }
    }

Effective Javaの著者Josh Blochが提唱した方式は,神の書き方,天然スレッドが安全で,自由にシーケンス化でき,反射生成インスタンスを防止できる.
参照先:https://www.cnblogs.com/jiangkuan/p/6031040.html https://www.cnblogs.com/zhaoyan001/p/6365064.html https://www.cnblogs.com/cielosun/p/6582333.html