Как блокировка (syncRoot) имеет смысл для статического метода? - PullRequest
3 голосов
/ 18 мая 2010

Следующий код извлекается из шаблона (Windows Identity Foundation SDK), который MS использует для создания нового веб-сайта службы маркеров безопасности.

public static CustomSecurityTokenServiceConfiguration Current  
{  
    get  
    {
        var key = CustomSecurityTokenServiceConfigurationKey;

        var httpAppState = HttpContext.Current.Application;

        var customConfiguration = httpAppState.Get(key)
            as CustomSecurityTokenServiceConfiguration;  

        if (customConfiguration == null)
        {  
            lock (syncRoot)
            {
                customConfiguration = httpAppState.Get(key)
                    as CustomSecurityTokenServiceConfiguration;  

                if (customConfiguration == null)
                {
                    customConfiguration =
                        new CustomSecurityTokenServiceConfiguration();  
                    httpAppState.Add(key, customConfiguration);
                }
            }
        }    
        return customConfiguration;  
    }
}

Я относительно новичок в многопоточном программировании. Я предполагаю, что причина утверждения lock состоит в том, чтобы сделать этот код потокобезопасным в случае, когда два веб-запроса поступают на веб-сайт одновременно.

Однако я бы подумал, что использование lock (syncRoot) не имеет смысла, поскольку syncRoot относится к текущему экземпляру, на котором работает этот метод ... но это статический метод!

Как это имеет смысл?

1 Ответ

6 голосов
/ 18 мая 2010

Оператор C # lock блокирует не метод, а объект, которому он предоставляется. В вашем случае syncRoot. Поскольку существует только один экземпляр этого объекта syncRoot, это гарантирует, что класс CustomSecurityTokenServiceConfiguration будет создан только один раз для этого домена приложения. Таким образом, свойство может быть вызвано и выполнено параллельно. Однако блок внутри lock { ... } никогда не будет вызываться параллельно. Однако его можно вызывать несколько раз, и это то, что делает дополнительный оператор if (customConfiguration == null) в блоке lock. Этот механизм называется двойной проверкой блокировки.

...