@Tejs,
Właściwie w .NET nie trzeba używać mechanizmu zamka podwójnego wyboru - istnieją lepsze sposoby wokół niego. Ale jeśli zdecydujesz się na to, twoja implementacja blokady podwójnego sprawdzenia jest nieprawidłowa i nie jest prawdziwie bezpieczna dla wątków. Kompilator mógł zoptymalizować dala inicjalizacji _instance = new PrintStringDataBuilder();
- są 3 możliwe modyfikacje, aby Państwa przykładem prawdziwie bezpieczne wątek:
- zainicjować statycznych inline - Zdecydowanie najłatwiej!
private static PrintStringDataBuilder _instance = new PrintStringDataBuilder;
public static PrintStringDataBuilder GetInstance()
{
return _instance;
}
2. użyj słowa kluczowego "volatile", aby upewnić się, że inicjalizacja PrintStringDataBuilder
nie została zoptymalizowana przez 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. Użyj opcji Interlocked.Exchange z blokadą z podwójną kontrolą:
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;
}
Mam nadzieję, że to pomoże.
To naprawdę zależy od tego, co robi 'nowy PrintStringDataBuilder()'. Próbujesz zrobić z tego Singleton? Jeśli tak, to tego nie robi. Jeśli nie, to dlaczego masz statyczną metodę 'GetInstance()', gdy możesz po prostu wywołać konstruktora. – cadrell0
Czy masz prywatnego konstruktora 'PrintStringDataBuilder' Jak są inicjowane inne pola? –
Dlaczego głosowanie w dół? Myślę, że to dobre pytanie. – n8wrl