デザインパターン-シンプルなシングルトン

デザインパターン-「単純な」シングルトン

概要

一部のシナリオでは、一部のクラスでは、オブジェクトのインスタンス化のみが必要な場合があります。このようなクラスはシングルトンクラスと呼ばれます。作成されたインスタンスオブジェクトは、オペレーティングシステムのタスクマネージャーなどのシングルトンオブジェクトと呼ばれます。システムリソースの使用状況、現時点で複数のオブジェクトがある場合、複数のオブジェクト間のデータの一貫性を維持する必要がありますが、プログラムの処理が煩雑になります。同様に、1回だけインスタンス化する必要があるスレッドプール、キャッシュ、ダイアログボックス、レジストリ、デバイスドライバーオブジェクトなどがあります。
クラス構造のみの観点から見ると、シングルトンパターンは最も単純な設計パターンである可能性がありますが、詳細については少し複雑です。クラス構造図を次の図に示します。
シングルトンパターン構造図

シングルトンパターンは、シングルトンクラスが最大で1回インスタンス化されることを保証し、グローバルアクセスポイントを提供します。


達成する

空腹

より直接的で安全な方法は、構築メソッドをプライベート化し、内部でインスタンスオブジェクトを構築し、シングルトンオブジェクトを取得するための静的アクセスメソッドを提供することです。サンプルコードは次のとおりです。

package singleton;

public class EagerSingleton {
    private static EagerSingleton instance = new EagerSingleton();

    private EagerSingleton() {
    }

    public static EagerSingleton getInstance() {
        return instance;
    }

}

内部インスタンスオブジェクトは、クラスが初期化されるときに作成され、シングルトンクラスは、オブジェクトへの外部アクセス用の静的アクセスメソッドgetInstance()を提供することがわかります。空腹スタイルの実装は、熱心なインスタンス化とも呼ばれます。この実装は、アプリケーションがインスタンスオブジェクトに常にアクセスするか、オブジェクトが作成および実行されるときにオブジェクトが多くのリソースを消費しないシナリオに適しています。

怠惰な

同様に、遅延インスタンス化の場合は、シングルトンオブジェクトを初めてインスタンス化し、後でアクセスするときにシングルトンオブジェクトを直接返す必要があるため、これを防ぐことができます。システムがオブジェクトにアクセスする必要がない場合の冗長オブジェクトの作成の問題を解決するため。実装の直接的な考え方は次のとおりです。

package singleton;

public class LazySingleton {
    private static LazySingleton instance = null;

    private LazySingleton() {
    }

    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

現時点で、マルチスレッド環境で発生する問題は、if判定ステートメントを同時に実行すると、複数のオブジェクトが作成され、シングルトンが保証されないことです。さらに、同期されたキーワードをメソッドに追加して、メソッドの実行を同期することを検討してください。

package singleton;

public class LazySingleton {
    private static LazySingleton instance = null;

    private LazySingleton() {
    }

    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

ダブルチェックロック

同期されたキーワードは、スレッドの同期を確実にしますが、マルチスレッドの状況でオブジェクトインスタンスを取得する際の非効率性ももたらし、同期ステートメントブロックのスコープを狭めます。if判定ステートメントブロック全体が同期している場合、オブジェクトを取得するたびに同期し、同期の範囲をさらに狭める必要があります。また、ダブルチェックロックの実装が次のように改善されています。

package singleton;

public class LazySingleton {
    private volatile static LazySingleton instance = null;

    private LazySingleton() {
    }

    public static LazySingleton getInstance() {
        if (instance == null) {
            synchronized (LazySingleton.class) {
                if (instance == null) {
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}

注:上記の実装メソッドは、リフレクションメカニズムを介してプライベート構築メソッドを呼び出すリスクがあります。プライベート構築メソッドに検証インスタンスの数を追加する判断についてさらに検討することができます。

列挙の実装

おそらく最も単純なシングルトン実装方法:

package singleton;

public enum Singleton {
    INSTANCE;
}

複数のインスタンス化のリスクを簡潔に回避し、シリアル化メカニズムを無料で提供し、「Effective Java」は、この方法がシングルトンを実現するための最良の方法になったとも述べています。


まとめ

  1. シングルトンパターンは、シングルトンクラスオブジェクトの一意性を保証します。これには特定のアプリケーションシナリオがあります。複数の実装方法がありますが、それらの長所と短所を明確にすると、これらの名詞に混乱することはなくなります。
  2. シングルトンパターンの構造は単純ですが、オブジェクトをインスタンス化するのは簡単ではありません。シリアライズ時の一意性の保証、マルチスレッドプログラミングにおけるvolatileの役割、クラスローダーの制限など、多くの基本的な知識があります。 、Xiaobianも常に蓄積しています。

参考文献

「大規模設計パターン」
「ヘッドファースト設計パターン」
「有効Java」
「設計パターンJava Edition」
[シングルトンパターンを正しく記述する方法]

PS:CSDNのシングルトン

この記事を書いている時点で、CSDNのシングルトンアプリケーションにひどく拷問されました。CSDNのマークダウンエディターを使用して記事の最後に書き込むと、同じブラウザーがCSDNの別のマークダウンエディターページを開き始めました。このとき、元の編集ページが再び開かれ、以前に保存していない下書きの内容が消えましたさて...私はそれを書き直さなければなりません/(ㄒoㄒ)/ ~~ @CSDN、これはバグですか?

元の記事を159件公開 賞賛された225件 210,000回の閲覧

おすすめ

転載: blog.csdn.net/lyg673770712/article/details/79635282