Skip to content

Instantly share code, notes, and snippets.

@tany3
Last active August 29, 2015 13:56
Show Gist options
  • Save tany3/8948225 to your computer and use it in GitHub Desktop.
Save tany3/8948225 to your computer and use it in GitHub Desktop.
C# シングルトンの実装 - 出所不明
/// <summary>
/// ダブルチェック ロッキングによるシングルトンを実装している。
/// </summary>
/// <remarks>
/// 静的な初期化はほとんどの状況に適応します。アプリケーションでインスタンス化を遅らせる必要がある場合や、既定以外のコンストラクタを使用したり、
/// インタンス化の前に他のタスクを実行したりする必要がある場合、またマルチスレッド環境で動作する必要がある場合は、別のソリューションが必要になります。
/// しかし、静的な初期化の例のように、共通言語ランタイムによってスレッド セーフを確保することができない場合もあります。
/// そのような場合は、特別な言語機能を使用することで、スレッドが複数存在するときに作成されるオブジェクトのインタンス数を確実に 1 つに制限する必要があります。
/// 一般的なソリューションの 1 つは、ダブルチェック ロッキング [Lea99] イディオムの使用によって、
/// 個々のスレッドがシングルトンの新しいインスタンスを同時に作成するのを阻止するようにすることです。
///
/// 次の実装では、Singleton のインスタンスがまだ作成されていないときに、lock ブロックで識別される重要な領域に、単一のスレッドのみがアクセスできるようになっています。
///
/// このアプローチでは、必ず 1 つのインスタンスのみが作成されるようになっています。また、この作成はインスタンスが必要となったときに初めて行われます。
/// さらに、変数が volatile として宣言されていることで、インスタンス変数への代入が完了するまでは、インスタンス変数にアクセスできなくなっています。
/// 最後に、このアプローチでは、syncRoot インスタンスをロックし、この型そのものをロックしないことで、デッドロックの発生を回避しています。
///
/// このダブルチェック ロッキング アプローチでは、Instance プロパティ メソッドの呼び出しごとの排他ロックを回避しながら、
/// 複数のスレッドの同時発生に関連する問題が解決されます。また、オブジェクトが初めてアクセスされるまで、インスタンス化を遅らせることも可能です。
/// 実際には、アプリケーションでこのタイプの実装が必要になることは稀です。ほとんどの場合は、初期化アプローチで充分に対応できます。
/// </remarks>
/// <see cref="http://msdn.microsoft.com/ja-jp/library/ms998558.aspx"/>
/// <seealso cref="http://msdn.microsoft.com/ja-jp/magazine/dd992855.aspx"/>
private static volatile SingletonTargetClass instance = null;
private static readonly object syncRoot = new object();
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment