(01)に記載のJavaデザインパターン:シングルトン

、シングルトン

1、の概念を説明します

定義のシングルトンデザインパターン:これが唯一のクラスのインスタンス、およびシステムが自動的にオブジェクトのインスタンス化を提供することを保証します。

2、サンプルコード

package com.model.test;
public class Singleton {
    // 使用静态变量记录唯一实例
    private static Singleton singleton = null;
    private Singleton (){}
    public static Singleton getInstance (){
        if (singleton == null){
            singleton = new Singleton() ;
        }
        return singleton ;
    }
    public static void main(String[] args) {
        Singleton singleton1 = Singleton.getInstance() ;
        Singleton singleton2 = Singleton.getInstance() ;
        /**
         * com.model.test.Singleton@15db9742
         * com.model.test.Singleton@15db9742
         */
        System.out.println(singleton1);
        System.out.println(singleton2);
    }
}

シングルトンは、例を作り出すことができるシステムを確保するために、シングルトンのコンストラクタprivate修飾子と呼ばれ、自動的に生成されました。上記のコードは、怠惰な人間の負荷として知られています:オブジェクトを使用した場合のみ、食べてちょうど空腹行うための手段を作成することでした。

第二に、セキュリティスレッド

上記のコードでは、複数のスレッドがオブジェクト・インスタンスを要求する場合、明らかセキュリティスレッド内に存在することは、オブジェクトを作成するために時間がかかるため、シングルトン== NULLを分析くるスレッドを想定し、オブジェクトを入力します作成プロセスは、その後、いくつかのスレッドを超えると同時に、それらは、オブジェクトのインスタンスを取得する場合は、これはいわゆるスレッド安全性の問題です。

図1に示すように、同期制御モード

package com.model.test;
public class Singleton {
    // 使用静态变量记录唯一实例
    private static Singleton singleton = null;
    private Singleton (){}
    public static synchronized Singleton getInstance (){
        if (singleton == null){
            singleton = new Singleton() ;
        }
        return singleton ;
    }
}

このような行動は、システムのパフォーマンスに影響を与えます

2、飢え型負荷

public class Singleton {
    // 使用静态变量记录唯一实例
    private static Singleton singleton = new Singleton();
    private Singleton (){}
    public static Singleton getInstance (){
        return singleton ;
    }
}

ここでは最初のうちオブジェクトを作成し、直接使用する必要があります。

3、ダブルチェック

public class Singleton {
    // 使用静态变量记录唯一实例
    // volatile可以确保当singleton被初始化后,多线程才可以正确处理
    // 被volatile修饰的变量的值,将不会被本地线程缓存
    // 对该变量读写都是直接操作共享内存,确保多个线程能正确的处理该变量。
    private static volatile Singleton singleton = null ;
    private Singleton (){}
    public static Singleton getInstance (){
        // 如果实例不存在,则进入同步区
        if (singleton == null){
            // 只有第一次才会彻底执行这里面的代码
            synchronized (Singleton.class) {
                if (singleton == null){
                    singleton = new Singleton() ;
                }
            }
        }
        return singleton ;
    }
}

4、列挙

package com.model.design.base.node01.singleton;
import org.junit.Test;
/**
 * 类级内部类里面创建对象实例
 */
public class C06_Singleton {
 @Test
 public void test01 (){
 SingletonDemo INSTANCE1 = SingletonDemo.INSTANCE ;
 SingletonDemo INSTANCE2 = SingletonDemo.INSTANCE ;
 System.out.println(INSTANCE1 == INSTANCE2);
 INSTANCE1.info();
 INSTANCE2.info();
 }
}
enum SingletonDemo {
 INSTANCE ;
 public void info (){
 System.out.println("枚举方式实现单例");
 }
}

第三に、遅延クラスの初期化

1、基本的な考え方

1)、クラスレベルの内部クラスは、
  簡単に言えば、クラスレベルの内部クラスは、内部クラス型のメンバの静的な変更があることを意味します。内部クラス型のメンバの静的な変更がない場合には、オブジェクトレベルの内部クラスと呼ばれています。
  オブジェクト外部の物体との間の依存関係が存在しない外側のクラスに対応する、その内部クラスのクラスレベルの静的成分、それが直接作成することができます。クラス内部のオブジェクトレベルの例が、外部オブジェクト・インスタンスにバインドされています。
  クラスレベルの内部クラスは、静的メソッドで定義することができます。唯一のメンバーは、静的メソッド、クラス外の静的メソッドまたはフィールドを指すことができます。
  クラスレベルの外部クラスに相当し、その内部クラスのメンバーと最初の時間は、使用されるのみであったロードされます。

デフォルトでは2)、マルチスレッド同期ロック
  主ミューテックス同期制御を追加するために、同期の使用を介して、並行性の問題を解決するためにマルチスレッドの開発です。しかし、いくつかのケースでは、JVMが暗黙的に同期を実行されている、これらの例は、独自のコントロールを同期させるために来ていません。これらは、次のとおりです。

  1.由静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时
  2.访问final字段时
  3.在创建线程之前创建对象时
  4.线程可以看见它将要处理的对象时

2、実装

非常に単純なスレッドセーフを実装するために、あなたは静的初期化子の方法を使用することができ、JVMのスレッドの安全性を確保するために行うことができます。例えば、空腹の人のタイプの実装の前に、一度クラスに関係なく、空間の一定の無駄があるかどうかの、オブジェクトを初期化するためにロードされます。
一つの可能な方法は、内部のこのクラスレベル内部クラスのオブジェクトのインスタンスを作成するために、クラスレベルの内部クラスを使用することです。その結果、彼らはクラス内部クラスにこのクラスを使用していない、それは同時に、遅延ロードとスレッドセーフを実現するために、オブジェクトのインスタンスを作成しません。

public class LazySingleton {
    /**
     * 类级内部类
     */
    private static class SingletonHolder {
        private static LazySingleton lazySingleton = new LazySingleton() ;
    }
    public static LazySingleton getInstance (){
        return SingletonHolder.lazySingleton ;
    }
    public static void main(String[] args) {
        LazySingleton lazySingleton1 = LazySingleton.getInstance() ;
        LazySingleton lazySingleton2 = LazySingleton.getInstance() ;
        /**
         * com.model.test.LazySingleton@15db9742
         * com.model.test.LazySingleton@15db9742
         */
        System.out.println(lazySingleton1+";;"+lazySingleton2);
    }
}

四、JDKのソースシングルトン

ランタイムシングルトンは、ソースを実現します。

1、ケース発表

/**
 * JDK 单例模式分析
 */
public class C07_Singleton {
 public static void main(String[] args) {
 Runtime runtime1 = Runtime.getRuntime() ;
 Runtime runtime2 = Runtime.getRuntime() ;
 /*
 * 1229416514
 * 1229416514
 */
 System.out.println(runtime1.hashCode());
 System.out.println(runtime2.hashCode());
 }
}

図2に示すように、ソースコード解析

public class Runtime {
 private static Runtime currentRuntime = new Runtime();
 public static Runtime getRuntime() {
 return currentRuntime;
 }
 private Runtime() {}
}

モードベースの実装を飢えシングルトン。

五、春Frameworkアプリケーション

1、テストクラスを作成します

public class UserBean {
}

2、Spring構成ファイル

<!-- 单例Bean -->
<bean id="user" 
class="com.model.design.spring.node01.singleton.UserBean" />

図3に示すように、被験者は、豆を読み出し

package com.model.design.spring.node01.singleton;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * Spring框架中单例模式
 */
public class S01_Singleton {
    @Test
    public void test01 (){
        ApplicationContext context01 = new ClassPathXmlApplicationContext("/spring/spring-context.xml");
        ApplicationContext context02 = new ClassPathXmlApplicationContext("/spring/spring-context.xml");
        UserBean user01 = (UserBean)context01.getBean("user") ;
        UserBean user02 = (UserBean)context01.getBean("user") ;
        UserBean user03 = (UserBean)context02.getBean("user") ;
        // com.model.design.spring.node01.singleton.UserBean@364841
        System.out.println(user01);
        // com.model.design.spring.node01.singleton.UserBean@364841
        System.out.println(user02);
        // com.model.design.spring.node01.singleton.UserBean@c4711c
        System.out.println(user03);
    }
}

結論
的に純粋な単一の設計パターンとスプリングシングルトン主な違い
アプリケーション・コンテキスト2をロードする同じクラスローダが、しかし実施例は、同じUserBeanのではありません。すなわち、シングルトンオブジェクトのSpringフレームワークは、アプリケーションに基づいています。

VIは、シングルトンをまとめたもの

1つの注意事項

单例模式注意事项和细节说明
1) 单例模式保证了 系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
2) 当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new Object() 的方式。
3) 单例模式使用的场景:需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象。

2、長所と短所

优点:
1、单例模式只会创建一个对象实例,减少内存消耗
2、设置全局访问点,优化共享资源的访问
缺点:
1、没有接口,很难扩展
2、不利于测试
3、与单一职责原则冲突

七、送信元アドレス

GitHub地址:知了一笑
https://github.com/cicadasmile/model-arithmetic-parent
码云地址:知了一笑
https://gitee.com/cicadasmile/model-arithmetic-parent


おすすめ

転載: www.cnblogs.com/cicada-smile/p/11204316.html