Potrzeba zmiennego lotnego w podwójnie sprawdzonym blokowaniu w .NET
Wiele tekstów mówi, że podczas implementowania podwójnie sprawdzonego blokowania w .NET pole, na którym się blokujesz, powinno mieć modyfikator lotny. Ale dlaczego dokładnie? Biorąc pod uwagę następujący przykład:
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
dlaczego „lock (syncRoot)” nie osiąga niezbędnej spójności pamięci? Czy nie jest prawdą, że po oświadczeniu „zablokuj” zarówno odczyt, jak i zapis byłyby niestabilne, a zatem niezbędna spójność zostałaby osiągnięta?