Что передать ключевому слову блокировки?

Каково различие (если таковые имеются) между использованием

void MethodName()
{
    lock(this)
    {
        // (...)
    }
}

или

private object o = new object();
void MethodName()
{
    lock(o)
    {
        // (...)
    }
}

?

Существует ли разница в производительности? Стиль? Поведение?

8
задан juan 23 February 2010 в 15:26
поделиться

4 ответа

Разница в том, что любой может заблокировать ваш экземпляр, но только вы можете заблокировать частный объект.

Это помогает предотвратить взаимоблокировки.

Например:

Допустим, Microsoft использовала lock (this) в классе Control .

Затем, если кто-то другой заблокирует экземпляр Control , его блокировка помешает запуску кода в Control , а это не то, что он хочет.

Это особенно плохо, если вы заблокируете типы, которые являются общими для всех доменов приложений

11
ответ дан 5 December 2019 в 05:18
поделиться

Шаблон I Обычно для класса, объявленного static ....

public static class SomeClass{
    private static object objLock = new object();
    ....
    public static object SomeProperty{
       get{ 
           lock(objLock){
             // Do whatever needs to be done
           }
       }
       set{
           lock(objLock){
           }
       }
    }
}

Точно так же для обычного класса я бы следовал этому шаблону:

public class SomeClass{
    private readonly object objLock = new object();
    ....
    public object SomeProperty{
       get{ 
           lock(objLock){
             // Do whatever needs to be done
           }
       }
       set{
           lock(objLock){
           }
       }
    }
}

Таким образом, никто не может заблокировать мой экземпляр и предотвратить возникновение взаимоблокировок ...

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

3
ответ дан 5 December 2019 в 05:18
поделиться

Есть разница в объеме и может быть разница в поведении (кстати, MS не рекомендует использовать "this"


// in this case, your lock object is public, so classes outside of this can lock on the same thing
lock(this) {}

// in this case, your lock is private, and only you can issue a lock statement against it
private object lockobj = new object()
..
lock(this.lockobj) {}

// this one is WRONG -- you willget a new object instance every time, so your lock will not provide mutual exclusion
void SomeMethod()
{
  // using a local variable for a lock -- wrong
  object obj = new object();
  lock(obj) {}
}

1
ответ дан 5 December 2019 в 05:18
поделиться

lock (this) заблокирует «текущий» объект.

Блокировка «this» обычно плохая идея, поскольку она открывает доступ к блокировке другому коду; Я предпочитаю иметь поле только для чтения, например:

public class Foo
{
    private readonly object padlock = new object();

    public void SomeMethod()
    {
        lock(padlock)
        {
            ...
        }
    }
}

Таким образом, все вызовы SomeMethod (и все остальное в Foo , которое блокирует замок ) будут заблокируйте тот же монитор для того же экземпляра Foo , но ничто другое не может помешать, заблокировав этот монитор.

На самом деле, если вы не имеете дело с «мошенническим» кодом, маловероятно, что другой код действительно заблокирует ссылку на экземпляр Foo , но это вопрос инкапсуляции.

17
ответ дан 5 December 2019 в 05:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: