Есть ли какая-либо причина для блокировки чего-то другого, кроме new object ()? - PullRequest
5 голосов
/ 19 марта 2011
object theLock = new object();

...


lock (theLock)
{
    ...
}

Я всегда использую new object() для этого, но мне интересно: есть ли обстоятельства, при которых вы бы использовали более конкретный тип?

Ответы [ 3 ]

5 голосов
/ 19 марта 2011

По моему мнению, любой ссылочный тип может быть заблокирован, причина, по которой фиктивный объект используется, состоит в том, чтобы избежать распространенных ошибок при блокировке:

Блокировка общих конструкций (это), заблокировать (typeof (MyType)) и заблокировать ("myLock") нарушать это правило:

  lock (this) is a problem if the instance can be accessed publicly.


  lock (typeof (MyType)) is a problem if MyType is publicly

доступны.

  lock("myLock") is a problem because any other code in the process

, используя ту же строку, поделится тот же замок.

4 голосов
/ 19 марта 2011

В случае new значение Type не имеет значения, экземпляр имеет значение. В этом случае вы говорите об объекте synclock : объекте, который используется для блокировки раздела (ов) кода (ов) для предотвращения одновременного доступа.

Использование другого Type, чем object для синхронизации, является пустой тратой памяти, потому что вы не используете этот экземпляр для чего-либо еще.

Существуют обстоятельства, при которых вы можете заблокировать другой тип: когда вам нужно заблокировать конкретный экземпляр. Основная проблема: экземпляр должен быть инициализирован, чтобы заблокировать его. И в большинстве случаев вы хотите синхронизировать инициализацию экземпляра:)

Но в некоторых случаях вы можете заблокировать экземпляр напрямую; как словарь например (ну почти прямо в этом случае;)).

private Dictionary<string,string> _dictionary = new Dictionary<string,string>();

public void AddValue(string key, string value)
{
    lock (((IDictionary)_dictionary).SyncRoot)    // SyncRoot recommended
    {
       if (!_dictionary.ContainsValue(value))
            _dictionary.Add(key, value);
    }
}

Но дело в том, что даже если это сработает, всегда спрашивайте себя: «Не лучше ли вместо этого создать конкретный блокирующий объект»?

3 голосов
/ 19 марта 2011

Я почти уверен, что вы знаете эту статью Заявление о блокировке (C # Reference) .

В общем, избегайте блокировки типа public или экземпляров, находящихся вне контроля вашего кода. Общие конструкции lock (this), lock (typeof (MyType)) и lock ("myLock") нарушают это правило:

  • блокировка (это) является проблемой, если Экземпляр может быть доступен публично.
  • блокировка (typeof (MyType)) - проблема если MyType общедоступен.
  • блокировка («myLock») является проблемой, так как любой другой код в процессе с использованием та же строка, поделится тем же блокировка.

Рекомендуется определить закрытый объект для блокировки или приватную статическую переменную объекта для защиты данных, общих для всех экземпляров.

...