2009-04-07 20 views
9

マルチスレッドのWinサービスでシングルトンを使用してロギングを行っていますが、遭遇する可能性のある問題は何かを知りたいと思っていました。私はすでに同期を処理するgetインスタンスを設定しましたマルチスレッドアプリケーションでシングルトンを使用する危険性は何ですか?

private static volatile Logging _instance; 
    private static object _syncRoot = new object(); 

    private Logging(){} 
    public static Logging Instance 
    { 
     get 
     { 
      if (_instance==null) 
      { 
       lock(_syncRoot) 
       { 
        if (_instance == null) 
        { 
         _instance = new Logging(); 
        } 
       } 
      } 
      return _instance; 
     } 
    } 

他に何か心配する必要があるものはありますか?

+1

ここはドラゴンズ!できる限り実行してください。 – Samuel

+1

"ドラゴンの事には介入しないでください。ケチャップでおいしいと味が良いです。 " –

答えて

13

それは私にはかなりよく見えます。

詳細については、Implementing the Singleton Pattern in C#を参照してください。

編集:おそらくロックの中に戻ります。

+1

良いリンク –

+0

の+1とインスタンスをnullと比較する前にロックしてください。 –

+0

@Joe本当に?そのことを考えていなかった.... –

0

ロギングのインスタンスメソッドがスレッドセーフな場合、心配することはないと思います。

3

シングルトンは、クラスによって具現化されたリソースにアクセスする際のボトルネックになる可能性があり、そうでなければ並行して使用できるリソースへの順次アクセスを強制します。

この場合、それは悪いことではないかもしれません。なぜなら、同じ瞬間に複数の項目にファイルを書き込ませたくないからです。その場合でも、実装でその結果が得られるとは思いません。しかしそれは気づくべきことです。

+0

私はむしろそれは私がシングルトンを使用してで探しています理由です多くの活動を持っていたとき起こっていたことである、クラッシュ後、ボトルネックとなります。 +1良い洞察力のため –

1

double-checked lockingあなたはアンチパターンとみなされているものを使用しています。 Wikipediaには、言語ごとに遅延初期化の有無を問わずパターンがあります。

シングルトンインスタンスを作成した後は、もちろん、すべてのメソッドがスレッドセーフであることを確認する必要があります。

12

これは他の情報よりも情報が豊富です。あなたが投稿した何

があるダブルチェックアルゴリズムロック - そしてあなたが私の知る限り承知しているとして、意志作品を掲載しましたが。 (Java 1.5では動作していますが)非常に脆弱です。間違ったことがあれば、非常に微妙な競合条件を導入することができます。

私は通常、静的初期化子でシングルトンを初期化することを好む:

public class Singleton 
{ 
    private static readonly Singleton instance = new Singleton(); 

    public static Singleton Instance 
    { 
     get { return instance; } 
    } 

    private Singleton() 
    { 
     // Do stuff 
    } 
} 

権利を取得するために、そのパターンの容易な

を(あなたは余分な怠惰のビットをしたい場合は、静的コンストラクタを追加します。)、及びほとんどの場合、それはちょうど良いことです。

さらに詳しくはC# singleton implementation page(マイケルとリンクしています)です。

危険については、最大の問題はテスト可能性を失うことだと思います。おそらくもありませんログには悪いです。

+0

あなたの記事へのリンクが壊れています。 –

+0

これはかなり悲しいですね。そのようなことは悪臭のある風邪をひいた投稿の危険です。修正されました。 –

+0

ここでプロパティを使用する理由は何ですか? public static readonlyフィールドを使用するのに十分安全ではないですか? –

1

シングルスレッドのセットアップ手順でロガーを確立することをお勧めします。必要なときに確実にそこにいることが保証されています。 Windowsサービスでは、OnStartはこれを実行するのに最適な場所です。

もう1つのオプションは、System.Threading.Interlocked.CompareExchange(T%、T、T):Tメソッドを使用して切り替えることです。それほど混乱せず、働くことが保証されています。

System.Threading.Interlocked.CompareExchange<Logging>(_instance, null, new Logging()); 
+0

私はC#のエキスパートではありませんが、すべての呼び出しで新しいLoggingインスタンスが生成されると思います。 'new Logging()'部分は、InterlockedCompareExchange内部の原子検査の前に実行されます。 –

+0

あなたはそうです。それは実際にはLoggingコンストラクタ(および初期化子)のセマンティクスに依存します。私はそれがまだ機能し、最初の提案が良いと思っています。 –

2

ロガーの各メソッドが同時に実行されても安全であること、つまり、適切なロックなしで共有状態に書き込まれないようにする必要があります。ヌル利用Thread.VolatileRead()あなたは二重のチェックをロックパターンを使用したい場合は、それはすべてのメモリモデルで作業するための最初のチェックを行う必要があるに関して、いくつかの議論があり

+0

シングルトンを使用しないと同時に実行できないのですか?私はそれがポイントだと思った。 –

+0

いいえ、複数のスレッドが単一のLoggingインスタンスに引き続きアクセスできます。そのメソッドはスレッドセーフである必要があります。 +1これをもたらすために。 – Lucas

+0

@bob:ダブルチェックロックは、(シングルトンを保証するために)複数のインスタンスの作成を防ぎますが、複数のスレッドからの同時アクセスを妨げません。 – Lucas

関連する問題