ホームページ  >  記事  >  Java  >  Java シングルトン パターンを完全にマスターする

Java シングルトン パターンを完全にマスターする

WBOY
WBOY転載
2022-04-13 19:04:081854ブラウズ

この記事では、java に関する関連知識を提供します。主にシングルトン モードに関する関連問題を紹介します。つまり、クラスにはインスタンスが 1 つだけあり、クラスはこのインスタンスを独自に作成できます。一緒に見てみましょう。皆さんのお役に立てれば幸いです。

Java シングルトン パターンを完全にマスターする

推奨される学習: 「

Java ビデオ チュートリアル

シングル ケース モード:

#まず、Java には 23 のデザイン パターンがあります。

    クリエイティブ パターン
  • : ファクトリ メソッド パターン、抽象ファクトリ パターン、シングルトン モード、ビルダー モード、プロトタイプ モード
  • 構造モード:
  • アダプター モード、デコレーター モード、プロキシ モード、アピアランス モード、ブリッジ モード、コンビネーション モード、フライウェイト モード
  • 行動パターン:
  • : 戦略パターン、テンプレートメソッドパターン、オブザーバーパターン、反復サブパターン、責任連鎖パターン、コマンドパターン、メモパターン、状態パターン、ビジターパターン、メディエーターパターン、インタープリターモード。
1. シングルトン パターンとは:

定義:

は、クラスのインスタンスが 1 つだけであることを意味します。このインスタンスを独自に作成するクラス A パターン。これにより、タスクマネージャーのウィンドウを複数開くことによるメモリリソースの浪費や、各ウィンドウの表示内容に一貫性がないなどのエラーを回避できます。たとえば、コンピューターではタスク マネージャーを 1 つだけ開くことができますか?そうです、これはリソースの無駄やその他のエラーを防ぐためです。
プロジェクトでは、通常、シングルトン モードで同じオブジェクトを取得してツール メソッドを呼び出すことができます。この利点は、メモリ リソースを節約できることです。メモリ リソースを消費するため、複数の異なるオブジェクトを作成する必要はありません

要約:

シングルトンは、インスタンスが 1 つだけあるプログラムです。このクラスは、独自のオブジェクトを作成します。同時に、 のみを保証する必要があります。 1 つの オブジェクトが作成されます

シングルトン モードの特徴:

Constructor private
  1. 独自の型のプロパティを保持します
  2. 外部にインスタンスを取得するための静的メソッドを提供します
シングルトン モードの構造図:


Java シングルトン パターンを完全にマスターする

2シングルトン モードの長所と短所:

利点:

メモリ オーバーヘッドの削減
  1. リソースの複数の占有を回避します
  2. グローバル アクセス ポイントの設定を最適化し、共有リソースにアクセスできる
  3. #欠点 (インターネットから参照):

一般的に、インターフェイスがないため拡張が困難です。拡張したい場合は、元のコードを変更する以外に方法はありません。これは、開始と終了の原則に違反します。

    同時テストでは、シングルトン モードはコードのデバッグには適していません。デバッグ プロセス中に、シングルトン内のコードが実行されていない場合、新しいオブジェクトの生成をシミュレートできません。
  1. シングルトン モードの関数コードは、通常、クラス内に記述されます。は不合理であり、簡単です。 単一責任の原則に違反するのは簡単です。
  2. シングルトン モードのマインド マップを見てください:

3. 遅延モード (より一般的に使用されます)

遅延モードの特徴は、初期化が遅れることです。インスタンスを取得するメソッドが呼び出されるまで、オブジェクトはインスタンス化されません。 スレッドではありません。 -safe。厳密に言えば、これはシングルトン モードではありません。利点は、インスタンスが取得されるまで作成されないことです。したがって、オブジェクトはメモリ オーバーヘッドを節約します

#Demo:

public class SingLeton {

    //1、有自己类型的属性
    private static SingLeton instance;

    //2、构造器私有化
    private SingLeton(){}

    //3、对外提供获取实例的静态方法
    public static SingLeton getInstance(){
        if (instance == null){
            instance = new SingLeton();
        }
        return instance;
    }}

テスト クラス:

public class Test {
    public static void main(String[] args) {

        //判断是否产生的是同一个对象
        SingLeton s1 = SingLeton.getInstance();
        SingLeton s2 = SingLeton.getInstance();
        System.out.println(s1 == s2);
    }}

出力:

true

注:

遅延モードのスレッドが安全ではないことについて

遅延モードのスレッドが安全ではないことがわかりました。次に、ロック (同期) を使用して同期する必要があります。

/**
 *   保证 instance 在所有线程中同步
 */public class SingLeton2 {

        //1、有自己类型的属性
        private static volatile SingLeton2 instance ;    
        
        //2、构造器私有化
        private SingLeton2() {
        }

        public static synchronized SingLeton2 getInstance() {
            //getInstance 方法前加同步
            if (instance == null) {
                instance = new SingLeton2();
            }
            return instance;
        }
    }
マルチスレッドを作成している場合は、上記のコード例でキーワード volatile および synchronized を削除しないでください。削除しないと、スレッドの非安全性の問題が発生します。これら 2 つのキーワードを削除しない場合、

スレッドの安全性を確保できますが、アクセスするたびに同期が必要となり、パフォーマンスに影響を及ぼし、より多くのリソースを消費します。これが遅延シングルトンの欠点です。

4. ハングリーマン モード [推奨]

ハングリーマン モードはスレッドセーフで一般的に使用されますが、ハングリーマン モードはロードされるため、ガベージ オブジェクトが生成されやすいです。先頭のクラス インスタンスが初期化されます

##Demo:

/**
 *
 * 饿汉模式
 */public class SingLeton {

    //持有自己类型的属性   (和懒汉一样)
    //由于static修饰,只在类加载的时候执行一次,类加载的时候就实例化对象
    private static SingLeton instance = new SingLeton();

    //构造器私有化,不能通过它创建对象
    private SingLeton(){};

    //对外提供获取实例的静态方法
    public static SingLeton getInstance(){
        return instance;
    }}


Test class:

public class Test {
    public static void main(String[] args) {

        //判断是否产生的是同一个对象
        SingLeton s1 = SingLeton.getInstance();
        SingLeton s2 = SingLeton.getInstance();
        System.out.println(s1 == s2);
    }}
Output:

true
怠け者モードと空腹者モードの比較:

  1. 懒汉模式延迟加载,非线程安全,饿汉模式线程安全
  2. 懒汉模式刚运行不实例化对象,需要的时候才实例化对象,相当于来讲更节省内存开销
  3. 饿汉模式只要运行都会加载类的时候就给你初始化了,就需要使用更大的内存

图解:
Java シングルトン パターンを完全にマスターする

5、单例模式的应用场景:

  1. 需要经常创建的一些类,使用单例可以降低系统的内存压力
  2. 这个类只要求生成一个对象的时候,比如每个人的名字
  3. 类创建实例时占用资源较多,或实例化耗时较长,且经常使用
  4. 频繁访问数据库或文件的对象
  5. 类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池

6、单例模式的应用实例

这里使用懒汉式单例模式模拟产生班级的班长
分析: 在每一个学期内,班级的班长只有一人,所以适合用单例模式实现

Person类:

/**
 * 使用懒汉模式
 */public class Person {

    //保证instance在所有线程中同步
    private static volatile Person instance;

    private Person(){
        System.out.println("产生一个班长");
    }

    //加上synchronized锁
    public static synchronized Person getInstance(){
        if(instance == null){
            instance = new Person();
        }else {
            System.out.println("错误信息:已经有一个班长,不能再产生");
        }
        return instance;
    }

    public void getName(){
        System.out.println("我是班长:小强");
    }}

测试类:

public class Test {
    public static void main(String[] args) {

        Person p1 = Person.getInstance();
        p1.getName(); //输出班长名字

        Person p2 = Person.getInstance();
        p2.getName();

        if(p1 == p2){
            System.out.println("两个班长是同一个人");
        }else {
            System.out.println("两个班长是同一个人");

        }
    }}

运行结果:

产生一个班长
我是班长:小强
错误信息:已经有一个班长,不能再产生
我是班长:小强
两个班长是同一个人

小结:

这个就是单例模式,当程序已经产生一个对象后,就不会产生一个新的对象,即使有多个对象也是同一个对象而已,在使用懒汉模式的时候需要注意线程安全问题,在平时更加推荐使用饿汉模式,也需要注意资源的占用。

推荐学习:《java教程

以上がJava シングルトン パターンを完全にマスターするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。