いもづる オブジェクト指向

 

シングルトンクラス

(2006/08/10)

up(2006/09/07)

シングルトンクラスとは、インスタンスが1つしか存在し得ない(シングル)ようなクラスのことをいいます。 下に処理は何もないシングルトンにするためだけのソースコードを示します。

 1|using System;
 2|
 3|namespace ioo.Sample.Singleton
 4|{
 5|    public class SmpSingle
 6|    {
 7|        private static SmpSingle instance_ = null;
 8|
 9|        private SmpSingle(){
10|        }
11|
12|        public static SmpSingle GetInstance(){
13|            if(instance_ == null){
14|                instance_ = new SmpSingle();
15|            }
16|            return instance_;
17|        }
18|    }
19|}

コンストラクタが private になっているために、外部からこのクラスを new することはできません。 外部に公開されているものは、static の GetInstanceメソッド のみです。
従ってこののインスタンスを得るには、

SmpSingle obj = SmpSingle.GetInstance();

のようにするしかありません。 またGetInstance内を見てもらえればわかるように、インスタンスが2つになることはありません。
このようにクラスはただの雛型ではなく、このようにインスタンスの制御をすることもできます。

しかし上のソースではマルチスレッドでの動作が考慮されていないため完全ではありません。
13行目でnullと判定した後14行目でインスタンスを生成するまでの間に、 別のスレッドが13行目の判定を行った場合は、そのスレッドでの動作もifの中に処理が入り2つ目のインスタンスを生成してしまいます。

確実なシングルトンの実装は以下となります。

 1|using System;
 2|
 3|namespace ioo.Sample.Singleton
 4|{
 5|    public class SmpSingleton
 6|    {
 7|        private static SmpSingleton instance_ = null;
 8|
 9|        private SmpSingleton(){
 0|        }
11|
12|        public static SmpSingleton GetInstance(){
13|            if(instance_ == null){
14|                lock(typeof(SmpSingleton)){
15|                    if(instance_ == null){
16|                        instance_ = new SmpSingleton();
17|                    }
18|                }
19|            }
20|
21|            return instance_;
22|        }
23|    }
24|}

lockステートメントを使用することで、lockの内部には1つのスレッドしか入れなくなります。 そこでインスタンスの存在確認を行い、未生成の場合は生成を行います。

13行目と15行目で同じ内容を2回行っていますが、これはlock処理が非常に負荷が高いため、 ひとまずnullであるかを判定した後に、クリティカルセクション内で「判定&nullの場合は生成」としています。

 

webmaster@e-ioo.net