単例類JAVA設計モード
基本概念
Singletonは、インスタンスが1つだけ生成することを保証し、グローバルアクセスポイントを提供するための作成モデルである.一部のクラスでは、データベース接続やSocket接続が一定の制限を受ける場合があり、同じ時間に1つの接続しか存在しないことを保証することが重要である.さらに例を挙げると、集合中のsetには重複する要素を含めることができず、setに追加するオブジェクトは一意でなければならず、重複する値がsetに追加されると、1つのインスタンスしか受け入れられない.JDKではSingletonモードを正式に運用してsetを実現しているのでjavaを見ることができます.util.Collectionsの内部静的クラスSingletonSetの元のコード.実はSingletonは最も簡単であるが最も広く応用されているモードの一つであり、JDKの中で随所に見られる.
Singletonモードを実現する方法は通常3種類ある.
一.Singletonを静的方法で実現する方法は静的方法を用いてインスタンスの作成を監視することである.以上のインスタンスを作成しないように、コンストラクタをprivateとして宣言したほうがいいです.
単一クラスの実装:
上記の実装はスレッドが安全ではありません!次の実装はスレッドが安全です.
public class Singleton{private volatile static Singleton uniqueInstance;private Singleton(){}//コンストラクション関数は、外部の痛みを防ぐためにnewがpublic static Singleton getInstance(){if(uniqueInstance==null){synchronized(Singleton.clss){if(uniqueInstance==null){{ uniqueInstance=new Singleton() } }}return uniqueInstance;}}ここでvolatileキーワード:このキーワードで修飾された変数はアクセスされるたびに、共有メモリから変数の値を読み直すように強制されます.変数の値が変化すると、スレッドに共有メモリに値を書き込むように強制されます.これにより、いつでも異なるスレッドで変数の同じ値が表示されます.コンパイラと実行時にこの変数が監視され、共有され、他のメモリ操作とともに並べ替えられません.
二.サイレント変数をフラグとして実現Singletonはクラスに1つの静的変数を埋め込むことをフラグとし,毎回コンストラクタに入るときに検査を行う.
三.レジストラ機構によりSingletonを作成するには、まず集合中のHashtableとEnumerationでaddItem(Object key,Object value)、getItem(Object key)、removeItem(Object key)などの方法でマネージャを実現し、keyとvalueを1つずつ関連付け、ゲストプログラマーがインスタンスを作成する前にaddItemメソッドで登録し、getItemメソッドでインスタンスを取得する.Hashtableのkeyは一意であるため、作成したインスタンスが一意であることを保証する.レジストラ機構を用いるSingletonモードを作成する利点は、管理が容易であり、複数の異なるタイプのSingletonインスタンスを同時に制御できることである.
Singletonは、インスタンスが1つだけ生成することを保証し、グローバルアクセスポイントを提供するための作成モデルである.一部のクラスでは、データベース接続やSocket接続が一定の制限を受ける場合があり、同じ時間に1つの接続しか存在しないことを保証することが重要である.さらに例を挙げると、集合中のsetには重複する要素を含めることができず、setに追加するオブジェクトは一意でなければならず、重複する値がsetに追加されると、1つのインスタンスしか受け入れられない.JDKではSingletonモードを正式に運用してsetを実現しているのでjavaを見ることができます.util.Collectionsの内部静的クラスSingletonSetの元のコード.実はSingletonは最も簡単であるが最も広く応用されているモードの一つであり、JDKの中で随所に見られる.
Singletonモードを実現する方法は通常3種類ある.
一.Singletonを静的方法で実現する方法は静的方法を用いてインスタンスの作成を監視することである.以上のインスタンスを作成しないように、コンストラクタをprivateとして宣言したほうがいいです.
単一クラスの実装:
public class Singleton {
private static Singleton s;
private Singleton(){};
/**
* Class method to access the singleton instance of the class.
*/
public static Singleton getInstance() {
if (s == null)
s = new Singleton();
return s;
}
}
//
class singletonTest {
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
if (s1==s2)
System.out.println("s1 is the same instance with s2");
else
System.out.println("s1 is not the same instance with s2");
}
}
上記の実装はスレッドが安全ではありません!次の実装はスレッドが安全です.
public class Singleton{private volatile static Singleton uniqueInstance;private Singleton(){}//コンストラクション関数は、外部の痛みを防ぐためにnewがpublic static Singleton getInstance(){if(uniqueInstance==null){synchronized(Singleton.clss){if(uniqueInstance==null){{ uniqueInstance=new Singleton() } }}return uniqueInstance;}}ここでvolatileキーワード:このキーワードで修飾された変数はアクセスされるたびに、共有メモリから変数の値を読み直すように強制されます.変数の値が変化すると、スレッドに共有メモリに値を書き込むように強制されます.これにより、いつでも異なるスレッドで変数の同じ値が表示されます.コンパイラと実行時にこの変数が監視され、共有され、他のメモリ操作とともに並べ替えられません.
二.サイレント変数をフラグとして実現Singletonはクラスに1つの静的変数を埋め込むことをフラグとし,毎回コンストラクタに入るときに検査を行う.
class SingletonException extends RuntimeException {
public SingletonException(String s) {
super(s);
}
}
class Singleton {
static boolean instance_flag = false; // true if 1 instance
public Singleton() {
if (instance_flag)
throw new SingletonException("Only one instance allowed");
else
instance_flag = true; // set flag for 1 instance
}
}
//
public class singletonTest {
static public void main(String argv[]) {
Singleton s1, s2;
// create one incetance--this should always work
System.out.println("Creating one instance");
try {
s1 = new Singleton();
} catch (SingletonException e) {
System.out.println(e.getMessage());
}
// try to create another spooler --should fail
System.out.println("Creating two instance");
try {
s2 = new Singleton();
} catch (SingletonException e) {
System.out.println(e.getMessage());
}
}
}
三.レジストラ機構によりSingletonを作成するには、まず集合中のHashtableとEnumerationでaddItem(Object key,Object value)、getItem(Object key)、removeItem(Object key)などの方法でマネージャを実現し、keyとvalueを1つずつ関連付け、ゲストプログラマーがインスタンスを作成する前にaddItemメソッドで登録し、getItemメソッドでインスタンスを取得する.Hashtableのkeyは一意であるため、作成したインスタンスが一意であることを保証する.レジストラ機構を用いるSingletonモードを作成する利点は、管理が容易であり、複数の異なるタイプのSingletonインスタンスを同時に制御できることである.