定義:クラスのインスタンスを1つだけ確実にするために、それはグローバルなアクセスポイントへのアクセスを提供します。
Singletonパターンの構成図:
シングルトンは、長所と短所の様々なを書いていて、今、私たちは執筆の様々なモードを見てみましょう。
1.飢えモード
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){
}
public static Singleton getInstance() {
return instance;
}
}
初期化が完了したときに、クラスがロードされる。このように、クラスのロードが遅いですが、すぐにオブジェクトの速度を取得します。このように、クラスローディング機構に基づいて複数のスレッドの同期を回避できますが、必ず他の方法(または他の静的メソッド)が存在することはできませんクラスローダをリードし、インスタンスを初期化するために、この時間は、明らかに怠惰なロードされたの効果を達成できませんでした。
2.レイジーモード(スレッドセーフ)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
レイジーモードは、静的オブジェクト、資源を節約しながら、ユーザーの最初の呼び出しが、しかし必要がインスタンス化されるときに初期化を宣言するときに、マルチスレッドで最初のロード、わずかに遅い反映しますが、しない作品。
3.レイジーモード(スレッドセーフ)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
私はこれをお勧めしませんので、このようなアプローチは、マルチスレッドでうまく動作することができますが、必要性は、ほとんどの時間は、我々は以下の同期化され、不要な同期オーバーヘッドを引き起こし、getInstanceメソッドが呼び出されるたびに同期して、することがモード。
4.ダブルチェックモード(DCL)
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){
}
public static Singleton getInstance() {
if (instance== null) {
synchronized (Singleton.class) {
if (instance== null) {
instance= new Singleton();
}
}
}
return singleton;
}
}
シングルトンのgetSingleton方法における文言は、二回第二がヌルに等しいシングルトンの場合にインスタンスを作成するだけであった、不要な同期のために最初に空気を宣告されました。でvolatileキーワードをここで使用されている、あなたは自分のネットワークvolatileキーワード検索クエリを理解することはできません。ここで使用多かれ少なかれ揮発性のパフォーマンスへの影響もよいが、プログラムの正しさを考慮し、この犠牲の性能はそれだけの価値があります。高いリソース利用のDCLの利点は、唯一のシングルトンオブジェクトがインスタンス化されたときのgetInstance最初のパフォーマンス、高効率。欠点は、あなたが最初の高い同時実行環境の中でわずかに遅い反応をロードする際に発生する確率は非常に小さいですが、また、いくつかの欠点を持っていることです。ある程度のリソースおよび冗長同期、スレッドの安全性やその他の問題の消費を解決するが、彼の障害が生じる場合がまだ疑問は、DCLは、無効であるが、DCL「の実践でのJava並行処理、」本が推奨する静的内部クラスのシングルトンパターンの代わりにDCLの。
静的な内部クラスのシングルトン
public class Singleton {
private Singleton(){
}
public static Singleton getInstance(){
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
SInstanceたときに最初のロードシングルトンクラス、仮想マシンの負荷SingletonHolder getInstanceメソッドへの最初の呼び出しだけを初期化し、sInstanceを初期化し、そのスレッドの安全性を保証できるだけでなく、シングルトンクラスの一意性を確保するためだけではなく、ではない静的な内部クラスを使用することをお勧めしますシングルトン。
6.列挙シングルトン
public enum Singleton {
INSTANCE;
public void doSomeThing() {
}
}
メソッドを呼び出します。
public class Main {
public static void main(String[] args) {
Singleton.INSTANCE.doSomething();
}
}
列挙インスタンスはスレッドセーフであり、単一の場合は、どのような場合には、あるデフォルトを作成し、いくつかのSingletonパターンは、上記の話を達成するために、そこに彼らはあるオブジェクトを、再作成することを一つのケース、デシリアライズ、Aディスクへのオブジェクトバックのシングルトンインスタンスは、それによって例を得、読み取ります。デシリアライゼーションオペレーションは、開発者がオブジェクトのデシリアライゼーションを制御することを可能にするreadResolveメソッドを提供します。次のようにそれを追加する必要があり、シングルトンオブジェクトは、オブジェクトがいくつかの方法の例は、上述した再生デシリアライズされて排除します。
プライベートオブジェクトはreadResolve()はObjectStreamException {スロー リターンシングルトンを、 }
単一例の利点を列挙簡単ですが、ほとんどのアプリケーション開発者はめったにお勧めしません、可読性が非常に高くない、列挙型を使用します。
最後に、その後、「効果的なJavaの」本を借ります
単一要素列挙型は、シングルトンを達成するための最良の方法となっています。
シングルモード用の容器の例7.
public class SingletonManager {
private static Map<String, Object> objMap = new HashMap<String,Object>();
private Singleton() {
}
public static void registerService(String key, Objectinstance) {
if (!objMap.containsKey(key) ) {
objMap.put(key, instance) ;
}
}
public static ObjectgetService(String key) {
return objMap.get(key) ;
}
}
より統合管理シングルトンクラスでSingletonManager、取得されたキーに応じてオブジェクトに対応するオブジェクト型を使用する場合。我々は、単一の実施形態の様々なタイプを管理することができるような方法では、取得され統一されたインタフェースを介して動作しているとき、ユーザーコストを削減するために使用されるだけでなく、結合の程度を減少させる、ユーザから隠蔽を実現することができます。
概要
ここに書かれた紹介の7は、複雑な同時実行環境、シングルトンオブジェクトまたはリソースの消費を制御する必要があるかどうか、プロジェクト自体に応じて、好みのシングルケースのモデルを形成するものととして、以上ですされています。