23のデザインパターン-シングルトンパターン[空腹のスタイル、怠惰なスタイル、ダブルチェック、静的な内部クラス、列挙]

一連の記事

23のデザインパターン-デザインパターンの目的と
23のデザインパターンに従う7つの原則-シングルトンモード[空腹、怠惰、ダブルチェック、静的内部クラス、列挙]
23のデザインパターン-ファクトリモード[シンプルファクトリ、ファクトリメソッド、抽象ファクトリ]
23のデザインモード-プロトタイプモード[クローンシープ、浅いコピー、深いコピー]


デザインパターンタイプ

1.作成モード:シングルトンモード、抽象ファクトリモード、プロトタイプモード、ビルダーモード、ファクトリモード。

2.構造モード:アダプターモード、ブリッジモード、装飾モード、組み合わせモード、外観モード、フライ級モード、エージェントモード。

3.動作モード:テンプレートメソッドモード、コマンドモード、ビジターモード、イテレーターモード、オブザーバーモード、メディエーターモード、メモモード、インタープリターモード、状態モード、戦略モード、責任連鎖モード。

注:異なる本の分類と名前は異なる場合があります。「DesignPatterns」には特別な本があります。

 

1.シングルトンモード

いわゆるシングルトンモードは、ソフトウェアシステム全体で、特定のクラスが1つのオブジェクトインスタンスのみを持つことができ、クラスがそのオブジェクトインスタンスを取得するために1つのメソッド(静的メソッド)のみを提供することを保証するために特定のメソッドを使用することです。

たとえば、MyBatisのSessionFactoryは、主にデータストレージソースのプロキシとして機能し、Sessionオブジェクトの作成を担当します。通常の状況では、SessionFactoryオブジェクトのみを使用する必要があるため、シングルトンモードです。

5つの主要なシングルトンモードがあります:空腹のスタイル(静的定数と静的コードブロックに細分されます)、怠惰なスタイル(スレッドセーフでない同期されたメソッド、同期されたコードブロックに細分されます)、ダブルチェック、静的内部クラス、列挙

 

空腹の中国人

静的変数法

public class SingletonTest01 {
    
    
    public static void main(String[] args) {
    
    
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();
        System.out.println(singleton1 == singleton2);//结果为true,两个对象相同
    }
}
//饿汉式(静态变量)
class Singleton{
    
    
    //1. 在该类内部创建实例对象
    private static final Singleton instance = new Singleton();
    //2. 构造器私有化,使外部不能通过new创建对象
    private Singleton(){
    
    }
    //3. 对外提供唯一一个公共静态方法,来获得该类对象
    public static Singleton getInstance(){
    
    
        return instance;
    }
}

長所と短所:

  1. 利点:書き込みメソッドは単純であり、クラスがロードされるとインスタンス化が完了するため、スレッド同期の問題が回避されます。
  2. 短所:クラスが読み込まれるときにインスタンス化され、遅延読み込みの効果が得られません(インスタンスは使用されたときにのみ作成され、それ以外の場合は作成されません。このインスタンスが使用されていない場合、無駄が発生しますメモリの)
  3. 結論:このシングルトンモード利用可能、 だが五月メモリの浪費を引き起こします。

 

静的コードブロック

public class SingletonTest02 {
    
    
    public static void main(String[] args) {
    
    
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();
        System.out.println(singleton1 == singleton2);//结果为true,两个对象相同
    }
}

//饿汉式(静态代码块)
class Singleton{
    
    
    //1. 在该类内部创建实例对象
    private static Singleton instance;
    //在静态代码块里实例化
    static {
    
    
        instance = new Singleton();
    }
    
    //2. 构造器私有化,使外部不能通过new创建对象
    private Singleton(){
    
    }
    //3. 对外提供唯一一个公共静态方法,来获得该类对象
    public static Singleton getInstance(){
    
    
        return instance;
    }
}

長所と短所:クラスのインスタンス化が静的コードブロックに配置されることを除いて、静的変数メソッドと同じですが、クラスがロードされるときにインスタンス化されます。

 

怠け者

スレッドセーフではありません

//饿汉式(静态代码块)
class Singleton{
    
    
    //1. 在该类内部创建实例对象
    private static Singleton instance;
    //2. 构造器私有化,使外部不能通过new创建对象
    private Singleton(){
    
    }
    //3. 对外提供唯一一个公共静态方法,来获得该类对象。当使用到该方法时,才创建对象。
    public static Singleton getInstance(){
    
    
        if (instance == null)
            instance = new Singleton();
        return instance;
    }
}

長所と短所:

  1. 遅延読み込み効果を再生できますが(インスタンスが使用された場合にのみ作成されます)、単一のスレッドでのみ使用できます。
  2. マルチスレッドでは、スレッドがifに入ったが、まだnewを実行しておらず、別のスレッドがif判定を行っている場合、これにより、最初のスレッドがnewで成功し、2番目のスレッドがifに入る可能性があります。 newの2番目のインスタンス。これにより、シングルトンパターンが破壊されます。
  3. 結論:実際の開発でこの方法使用しないでください

 

同期方法

//懒汉式(同步方法)
class Singleton{
    
    
    //1. 在该类内部创建实例对象
    private static Singleton instance;
    //2. 构造器私有化,使外部不能通过new创建对象
    private Singleton(){
    
    }
    //3. 对外提供唯一一个公共静态方法,来获得该类对象
    //改为同步方法 synchronized
    public static synchronized Singleton getInstance(){
    
    
        if (instance == null)
            instance = new Singleton();
        return instance;
    }
}

長所と短所:

  1. スレッドの不安定さの問題を解決します。
  2. 効率が低すぎます。同期されているため、各スレッドがクラスインスタンスを取得する場合は、同期する必要があります(このメソッドを使用するプロセスがなくなるのを待ちます)。ただし、このメソッドはインスタンス化時にのみ同期する必要があり、同期せずにインスタンスに戻るだけです。
  3. 結論:実際の開発では使用することはお勧めしません

 

同期コードブロック

//懒汉式(同步方法)
class Singleton{
    
    
    //1. 在该类内部创建实例对象
    private static Singleton instance;
    //2. 构造器私有化,使外部不能通过new创建对象
    private Singleton(){
    
    }
    //3. 对外提供唯一一个公共静态方法,来获得该类对象
    //改为同步代码块
    public static synchronized Singleton getInstance(){
    
    
        if (instance == null){
    
    
            synchronized(Singleton.class){
    
    
                instance = new Singleton();
            }
        }
        return instance;
    }
}

この方法では、スレッドの安全性すら解決されません。最初のスレッドが新しい場合でも、2番目のスレッドはif判定に合格し、その後も新しいためです。

 

再確認

//双重检查
class Singleton{
    
    
    //1. 在该类内部创建实例对象
    private static volatile Singleton instance;
    //2. 构造器私有化,使外部不能通过new创建对象
    private Singleton(){
    
    }
    //3. 对外提供唯一一个公共静态方法,来获得该类对象
    //加入双重检查代码,解决线程安全和懒加载问题,同时保证了效率
    public static Singleton getInstance(){
    
    
        if (instance == null){
    
    
            synchronized (Singleton.class){
    
    
                if (instance == null)
                    instance = new Singleton();
            }
        }
        return instance;
    }
}

 
揮発性キーワード:スレッドによる揮発性変数の変更は、他のスレッドによって即座に認識されます。つまり、データのダーティな読み取りがないため、データの「可視性」が保証されます。

長所と短所:

  1. ダブルチェックはマルチスレッド開発でよく使用されます。コードで2つのif判定を実行しました。3つのスレッドA、B、Cがある場合、AとBの両方が最初のifを通過すると、Aは同期コードブロックに入ります。最初。インスタンス化後に終了し、Bが同期コードブロックに入った後はインスタンスがnullにならないため、スレッドの安全性が確保されます。ただし、後続のCは最初のif判定に合格できないため、効率の問題は解決されます。
  2. スレッドセーフ、遅延読み込み、および高効率を実現します。
  3. 結論:実際の開発では、このシングルトンデザインパターンが推奨されます。

 

静的内部クラス

//静态内部类
class Singleton{
    
    
    //1. 在该类内部创建实例对象
    private static volatile Singleton instance;
    //2. 构造器私有化,使外部不能通过new创建对象
    private Singleton(){
    
    }

    //3. 编写静态内部类
    private static class SingletonInstance{
    
    
        private static final Singleton INSTANCE = new Singleton();
    }

    //4. 对外提供唯一一个公共静态方法,来获得该类对象
    public static Singleton getInstance(){
    
    
        return SingletonInstance.INSTANCE;
    }
}

長所と短所:

  1. 静的内部クラスの特徴の1つは、外部クラスのロードでロードされないことです。つまり、Singletonがロードされると、SingletonInstanceはロードされず、Singleton.INSTANCEが実行されたときにのみロードされるため、遅延読み込み効果。
  2. クラスの静的プロパティは、クラスが初めてロードされたときにのみ初期化されます。したがって、クラスの初期化時に他のスレッドが入ることができないため、ここでJVMはスレッドセーフを確保するのに役立ちます。
  3. スレッドセーフ、遅延読み込み、および高効率を実現します。
  4. 結論:推奨。

 

列挙する

package design_partten.singleton.type8;

public class SingletonTest08 {
    
    
    public static void main(String[] args) {
    
    
        Singleton singleton1 = Singleton.INSTANCE;
        Singleton singleton2 = Singleton.INSTANCE;
        System.out.println(singleton1 == singleton2);//结果为true,两个对象相同
        singleton1.sayOk();
    }
}

//静态内部类
enum Singleton{
    
    
    INSTANCE;
    public void sayOk(){
    
    
        System.out.println("ok~");
    }
}

長所と短所:

  1. JDK1.5で追加された列挙を使用してシングルトンモードを実装すると、マルチスレッド同期の問題を回避できるだけでなく、逆シリアル化によるオブジェクトの再作成を防ぐこともできます。
  2. 結論:推奨。

 

シングルトンモードのJDKソースコードの使用

ランタイムは、空腹のマンスタイルのシングルトンモードです。これは、ランタイムを使用することを保証できるため、メモリの浪費がなく、スレッドセーフも保証できるためです。

1615209917646

 

概要

  • シングルトンモードでは、システムメモリにこのクラスのオブジェクトが1つだけ存在するため、システムリソースが節約されます。頻繁に作成および破棄する必要がある一部のオブジェクトでは、シングルトンモードを使用するとシステムパフォーマンスを向上させることができます。
  • オブジェクトをインスタンス化する場合は、newを使用する代わりに、対応するオブジェクトの取得方法を使用することを忘れないでください。
  • シングルトンモードの使用シナリオ:頻繁に作成および破棄する必要があるオブジェクト、オブジェクトを作成するには時間またはリソースを消費するが、頻繁に使用する必要があるオブジェクト、ツールオブジェクト、データベースまたはファイルに頻繁にアクセスするオブジェクト(データ)ソース、SessionFactory)。

おすすめ

転載: blog.csdn.net/qq_39763246/article/details/114553165