Знаменитый метод блокировки с двойной проверкой в ​​C #

Я видел в книге по mprss эту рекомендацию синглтона (частичный код прилагается):

public static Singleton GetSingleton() 
{
    if (s_value != null) 
        return s_value;
    Monitor.Enter(s_lock); 
    if (s_value == null) 
    {
        Singleton temp = new Singleton();
        Interlocked.Exchange(ref s_value, temp);
    }
    Monitor.Exit(s_lock);
    return s_value;
}

Мы добавляем две строки кода во второй блок операторов if вместо того, чтобы просто писать:

s_value = new Singleton();

это должно обрабатывать ситуацию что второй поток входит в метод и находит s_value! = null , но не инициализируется.


У меня вопрос, можем ли мы вместо этого просто написать во втором блоке if:

{    
    Singleton temp = new Singleton();
    s_value = temp;  // instead of Interlocked.Exchange(ref s_value, temp);    
}

Итак, теперь функция:

public static Singleton GetSingleton() 
{      
    if (s_value != null)
        return s_value;

    Monitor.Enter(s_lock);   
    if (s_value == null)   
    { 
        Singleton temp = new Singleton();    
        s_value = temp; 
    }   
    Monitor.Exit(s_lock);   
    return s_value; 
} 

Думаю, нет, потому что они ее не используют.

Есть ли у кого-нибудь предложения?


Возможно, svalue может содержать неинициализированное? svalue можно построить сразу после полной инициализации temp (могу ли я ошибаться). если я ошибаюсь, можно указать пример, что это неправильно? может ли компилятор создать другой код?


6
задан roman 1 January 2012 в 15:23
поделиться