- シングルトンパターン(シングルトンパターン)は、Javaで最も単純なデザインパターンの1つです。このタイプのデザインパターンは、一般的なオブジェクトに最適な方法を提供する作成パターンです。
-
このパターンには、独自のオブジェクトの作成を担当する単一のクラスが含まれますが、単一のオブジェクトのみが作成されるようにします。このクラスは、このクラスのオブジェクトをインスタンス化せずに直接アクセスできる唯一のオブジェクトにアクセスする方法を提供します。
-
注:
-
-
1.シングルトンクラスはインスタンスを1つだけ持つことができます。
-
2.シングルトンクラスは、独自の一意のインスタンスを作成する必要があります。
-
3.シングルトンクラスは、このインスタンスを他のすべてのオブジェクトに提供する必要があります。
-
-
意図:クラスのインスタンスが1つだけであることを確認し、それにアクセスするためのグローバルアクセスポイントを提供すること。
-
主な解決策:グローバルに使用されるクラスが頻繁に作成および破棄されます。
-
使用する場合:インスタンスツリーを制御してシステムリソースを節約する場合。
-
解決方法:システムにすでにこのシングルトンがあるかどうかを判断し、ある場合は戻り、ない場合は作成します。
-
キーコード:コンストラクターはプライベートです。
-
アプリケーション例:
-
-
1.クラスには教師が1人だけです。
-
2. Windowsはマルチプロセスおよびマルチスレッドです。ファイルを操作する場合、複数のプロセスまたはスレッドが同時にファイルを操作することは避けられないため、すべてのファイルは一意のインスタンスを介して処理する必要があります。
-
3.一部のデバイスマネージャはシングルトンモードで設計されることがよくあります。たとえば、コンピュータには2つのプリンタがあり、2つのプリンタが出力時に同じファイルを印刷できないという問題に対処する必要があります。
-
-
利点:
-
-
1.メモリオーバーヘッド、特にインスタンスの頻繁な作成と破棄(WEBページキャッシュなど)を削減するために、メモリには1つのインスタンスしかありません。
-
2.リソース(ファイル書き込み操作など)の複数の所有を避けます。
-
-
短所:言い訳はなく、継承することはできず、単一責任の原則と矛盾しますクラスは内部ロジックのみを考慮し、外部でのインスタンス化方法は考慮しないでください。
-
使用シナリオ:
-
-
1.固有のシリアル番号の作成を要求します。
-
2. WEBのカウンターは、更新されるたびにデータベースに追加する必要はなく、最初に1つのケースでキャッシュされます。
-
3.オブジェクトを作成すると、I / Oからデータベースへの接続など、多くのリソースが消費されます。
-
注:getInstance()メソッドは、複数のスレッドが同時に入り、インスタンスが複数回インスタンス化されるのを防ぐために、同期ロック同期(Singleton.class)を使用する必要があります。
-
-
実際の戦闘:
-
-
SingleObjectクラスを作成します。SingleObjectクラスには、プライベートコンストラクターとそれ自体の静的インスタンスがあります。
-
SingleObjectクラスは、外部インスタンスが静的インスタンスを取得するための静的メソッドを提供します。
-
package singleton;
/**
* @author yangxin_ryan
*/
public class SingleObject {
// Create singleObject Object
private static SingleObject instance = new SingleObject();
// make construct private avoid instatiation
private SingleObject(){}
public static SingleObject getInstance(){
return instance;
}
public void showMessage() {
System.out.println("Hello World!");
}
}
package singleton;
/**
* @author yangxin_ryan
*/
public class SingletonPatternDemo {
public static void main(String[] args) {
SingleObject object = SingleObject.getInstance();
object.showMessage();
}
}
- 残りの実装バージョン
package singleton;
/**
* @author yangxin_ryan
* 懒汉式,线程不安全
* 这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程,因为没有加锁synchronized,所以严格意义上并不算单例模式;
*/
public class SingletObject1 {
private static SingletObject1 instance;
private SingletObject1() {}
public static SingletObject1 getInstance(){
if (instance == null) {
instance = new SingletObject1();
}
return instance;
}
}
package singleton;
/**
* @author yangxin_ryan
* 懒汉式,线程安全
* 这种方式具备很好的lazy loading,能够在多线程中很好的工作,但是效率很低,99%情况下不需要同步;
*/
public class SingletObject2 {
private static SingletObject2 instance;
private SingletObject2() {}
public static synchronized SingletObject2 getInstance(){
if (instance == null) {
instance = new SingletObject2();
}
return instance;
}
}
package singleton;
/**
* @author yangxin_ryan
* 饿汉式,线程安全
* 这种方式比较常见,但容易产生垃圾对象。它基于classloader机制避免了多线程的同步,不过instance在类装载时就实例化,
* 虽然导致类装载的原因有很多,在单例模式中大多数都是调用getInstance方法,但是也不能确定有其他的方式(或者其他静态方法)导致类加载。
* 这时候初始化intance显然没有达到lazy loading效果
*/
public class SingletObject3 {
private static SingletObject3 instance = new SingletObject3();
private SingletObject3(){}
public static SingletObject3 getInstance(){
return instance;
}
}
package singleton;
/**
* @author yangxin_ryan
* 双检索/双重校验锁,线程安全
* 这种方式采用双锁机制,安全且在多线程情况下能保持高性能
*/
public class SingletObject4 {
private volatile static SingletObject4 singleton;
private SingletObject4(){}
public static SingletObject4 getInstance() {
if (singleton == null) {
synchronized (SingletObject4.class) {
if (singleton == null) {
singleton = new SingletObject4();
}
}
}
return singleton;
}
}