ホームページ  >  記事  >  Java  >  シングルトンパターンの詳細な紹介

シングルトンパターンの詳細な紹介

王林
王林転載
2020-08-10 16:29:312528ブラウズ

シングルトンパターンの詳細な紹介

まず、シングルトン パターンの定義を見てみましょう。

シングルトン パターンは、Java で最も単純な設計パターンの 1 つであり、創造的なものです。オブジェクトを作成するための最良の方法を提供します。シングルトン パターンには、単一のオブジェクトのみが作成されるようにしながら、独自のオブジェクトの作成を担当する単一のクラスが含まれます。

(推奨チュートリアル: java 入門チュートリアル)

メモリ内にオブジェクトが 1 つだけ存在するようにするには、メモリ消費の原因となるオブジェクトの頻繁な作成を避け、そのため、このオブジェクトを呼び出す必要がある場合は常に、このシングルトン オブジェクトがすべて使用されます。

次に、シングルトン パターンのタイプを見てみましょう:

1. 遅延スタイル

遅延スタイルとは、シングルトンが必要な場合にのみ作成されることを意味します。

遅延スタイルのシングルトン パターンの実装:

public class Singleton {
	private static Singleton singleton;
	private Singleton(){
	
	}
	public static Singleton getInstance(){
		if (singleton == null) {
			singleton = new Singleton();
	    }
	    return singleton;
}

遅延スタイルのシングルトンの実装には問題があります。つまり、オブジェクトが 1 つだけ作成されるようにする方法です。 2 つ以上のスレッドが同時にシングルトンが空であると判断した場合、複数のオブジェクトが作成されます。したがって、スレッドの安全性の問題を解決する必要があります。

スレッド セーフというと思い浮かぶのはロックですが、ロックとはメソッドやクラス オブジェクトをロックすることに他なりません。

//在方法上加锁
public class Singleton {
	private static Singleton singleton;
	private Singleton(){}
	public static synchronized Singleton getInstance() {
    	if (singleton == null) {
        	singleton = new Singleton();
    	}
    return singleton;
	}
}

//在类对象上加锁
public class Singleton {
	private static Singleton singleton;
	private Singleton(){}
	public static Singleton getInstance() {
    synchronized(Singleton.class) {   
        if (singleton == null) {
            singleton = new Singleton();
        }
    }
    return singleton;
	}	
}

これら 2 つのメソッドは、シングルトン オブジェクトを同時に作成するマルチスレッドの問題を解決できますが、オブジェクトを取得するたびに最初にロックを取得する必要があり、同時実行パフォーマンスが低くなります。したがって、依然として最適化が必要です。最適化の目標は、インスタンス化されたオブジェクトがない場合はロックして作成し、インスタンス化されたオブジェクトがある場合は直接返すことです。

(学習ビデオの推奨: java コース)

メソッドをロックするには、インスタンス化されたオブジェクトの有無に関係なく、ロックが必要です。したがって、最適化する必要があるのは、クラス オブジェクトをロックすることです。

//DCL单例模式(Double Check + Lock)
public class Singleton {
	//volatite关键词防止指令重排序,下文介绍
	private static volatile Singleton singleton;
	private Singleton(){}
	public static Singleton getInstance() {
	//如果singleton不为空,则直接返回对象,若多个线程发现singleton为空,则进入分支
		if (singleton == null) {
		//多个线程同时争抢一个锁,只有一个线程能成功,其他线程需等待
			synchronized(Singleton.class) {
			//争抢到锁的线程需再次判断singleton是否为空,因为有可能被上个线程实例化了
			//若不为空则实例化,后续线程再进入的时候则直接返回该对象
			//对于之后所有进入该方法的线程则无需获取锁,直接返回对象   
        	if (singleton == null) {
           		singleton = new Singleton();
        	}
    		}
		}
    	return singleton;
	}	
}

命令の並べ替えを防ぐために、上記のコードに volatile キーワードが追加されています。

2. ハングリー チャイニーズ スタイル

ハングリー チャイニーズ スタイルとは、クラスのロード時にシングルトン オブジェクトが作成されることを意味します。

Hungry Chinese スタイルのシングルトン パターンの実装:

public class Singleton {
	private static final Singleton singleton = new Singleton();
	private Singleton(){
	
	}
	public static Singleton getInstance(){
		return singleton;
	}

概要:

Lazy Man スタイル: 必要な場合にのみオブジェクトをインスタンス化する開発中、メモリ要件が高い場合、マルチスレッド環境で遅延スタイルを使用する場合は、DCL シングルトン モードを使用する必要があります。DCL シングルトン モードを使用すると、同時実行セキュリティとパフォーマンスの低下の問題が解決されます。volatile キーワードを追加すると、次のような原因で発生する NPE 例外も防ぐことができます。命令の並べ替え。

Hungry Chinese スタイル: クラスのロード時にオブジェクトはすでにインスタンス化されています。メモリ要件が高くない場合は、Hungry Chinese スタイルを使用してください。シンプルでエラーが発生しにくく、必要な機能がありません。同時実行のセキュリティとパフォーマンスの問題。

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

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