@Tejs、
実際、.NETにあなたがダブルチェックロック機構を使用する必要はありません - それは周りのより良い方法があります。しかし、そうすることを選択した場合、ダブルチェックロックの実装は間違っており、本当にスレッドセーフではありません。コンパイラは_instance = new PrintStringDataBuilder();
の初期化を離れて最適化することができ - 3つの可能な変更は、本当にスレッドセーフあなたの例を作ることがあります。
- は、静的メンバをインラインで初期化する - 間違いなく最も簡単!
private static PrintStringDataBuilder _instance = new PrintStringDataBuilder;
public static PrintStringDataBuilder GetInstance()
{
return _instance;
}
2。 'volatile'キーワードを使用して、PrintStringDataBuilder
の初期化がJITによって最適化されていないことを確認してください。
private static volatile PrintStringDataBuilder _instance = null;
private static object _lockObject = new object();
public static PrintStringDataBuilder GetInstance()
{
if(_instance == null)
{
lock(_lockObject)
{
if(_instance == null)
{
_instance = new PrintStringDataBuilder();
}
}
}
return _instance;
}
3。ダブルチェックロックを使用してInterlocked.Exchangeを使用してください。
private static PrintStringDataBuilder _instance = null;
private static object _lockObject = new object();
public static PrintStringDataBuilder GetInstance()
{
if(_instance == null)
{
lock(_lockObject)
{
if(_instance == null)
{
var temp = new PrintStringDataBuilder();
Interlocked.Exchange(ref _instance, temp);
}
}
}
return _instance;
}
希望します。
これは本当に '新しいPrintStringDataBuilder()'が何をするかによって異なります。それをシングルトンにしようとしていますか?もしそうなら、これはそうしていない。そうでなければ、コンストラクタを呼び出すだけで静的な 'GetInstance()'メソッドを持っているのはなぜですか? – cadrell0
プライベートコンストラクタ 'PrintStringDataBuilder'をお持ちですか他のフィールドはどのように初期化されていますか? –
なぜ落選ですか?私は良い質問だと思う。 – n8wrl