2013-12-03 6 views
3

Я пытаюсь изучить потоки в C#, и я видел, что что-то появилось в нескольких статьях, но я не уверен, что полностью его понимаю: В данной два примера, каково было бы принципиальное различие между фиксацией «этого» и «thisLock».Получение блокировки с использованием объекта, а не это - Threading

Пример 1:

class Account 
    { 
     decimal balance; 
     private Object thisLock = new Object(); 

     public void Withdraw(decimal amount) 
     { 
      lock (thisLock) 
      { 
       if (amount > balance) 
       { 
        throw new Exception("Insufficient funds"); 
       } 
       balance -= amount; 
      } 
     } 
    } 

Пример 2:

class Account 
    { 
     decimal balance; 

     public void Withdraw(decimal amount) 
     { 
      lock (this) 
      { 
       if (amount > balance) 
       { 
        throw new Exception("Insufficient funds"); 
       } 
       balance -= amount; 
      } 
     } 
    } 

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

Были ли попытки блокировки «этого» остановить все операции над объектом, то есть вызовы других методов другими потоками?

Неужели я принципиально пропустил это, или это правильный вывод?

+3

ли [это] помогает (http://stackoverflow.com/questions/251391/why-is-lockthis-bad) ? –

+2

Предложение Шрирама - это ответ - чтобы быть ясным, 'lock (this)' ничем не отличается от 'lock (somethingEls e) «если смотреть изолированно. – Jon

ответ

2

Оба случая будут иметь одинаковый эффект. Одно из отличий заключается в том, что другие объекты не видят thisLock, поэтому вы можете быть уверены, что ничто другое не будет повторно использовать блокировку. Если вы заблокируете this, другая часть кода также может быть заблокирована на том же экземпляре учетной записи.

+0

_ «вы можете быть уверены, что ничто другое не будет повторно использовать блокировку» _ - пока какой-либо другой метод в этом классе не использует тот же объект блокировки. – CodeCaster

+0

@CodeCaster: Конечно, это то, что вы, автор этого класса, имеете полный контроль над :-) – Steven

0

Вы заявили

Из моего понимания, я бы мысли, что «thisLock» только останавливает других потоков ввода этой конкретной области кода.
Были ли попытки блокировки 'this' остановить все операции над объектом, т. Е. Называть другие методы другими потоками?

Используете ли вы lock(this) или lock(thisLock) в обоих заявлениях, он останавливается только другие потоки от ввода этой конкретной области кода.
Но в качестве общей практики всегда рекомендуется не использоватьlock(this) скорее создайте другой объект и поместите lock на этот объект.

EDIT да как Sriram Sakthivel прокомментировал, что он абсолютно прав, пожалуйста, прочитайте Why is lock(this) {...} bad? для получения дополнительной информации, почему мы должны избегать lock(this)

+2

Совет, чтобы не использовать 'lock (this)', должен быть размещен в перспективе. В Руководстве по дизайну рамок советуются против этого, потому что это плохо с точки зрения каркаса. Пользователь вашей инфраструктуры всегда может блокировать экземпляр типа в вашей структуре, что может случайно привести к тупиковой ситуации. При написании приложения LOB существует полный контроль над тем, какой код написан, и это может быть не такой большой проблемой. Я бы сказал, что в этом случае 'lock (this)' отлично, но использование блокировки экземпляра другого типа на самом деле является плохой практикой. – Steven

+1

Исправлена ​​ошибка, ссылка была связана с ссылкой текущего вопроса :) –

1

Разницы блокировки зернистости.

При блокировке объекта (бит) бит устанавливается на экземпляре. Любой, кто пытается заблокировать один и тот же экземпляр, окажется в состоянии ожидания, пока блокировка не будет освобождена другим.

Во многих случаях методы на объекте могут использоваться одновременно (например, параллельно). Блокирование всего объекта (это) исключает использование любого другого метода, если этот метод также использует «lock(this)».

Поскольку блокировка может использоваться для любого ссылочного типа, мы можем создавать объекты «блокировки». Где мы реализуем «lock(lockObject)» на основе исключения.

В качестве примера;

  • MethodA1 и MethodA2 не могут быть использованы в то же время
  • MethodB1 и MethodB2 не могут быть использованы в то же время

  • MethodA1/2 могут быть использованы в то же время, как MethodB1/2.

Если мы будем использовать lock(this) на каждом методе, мы также были бы exluding MethodA1/2 от запуска в то же время, как MethodB1/2.

Создав 2 объекта блокировки (lockAMethods, lockBMethods), мы можем теперь реализовать нашу блокировку более гранулированной.

  • В MethodA1 и MethodA2 мы будем использовать «lock(lockAMethods)», чтобы убедиться, что методы А1 и А2 не могут работать одновременно.
  • В MethodB1 и В2 мы будем использовать "lock(lockBMethods) ", чтобы убедиться, что B1 и B2 методы не могут работать одновременно.

Мы можем, однако lock(lockAMethods) и lock(lockBMethods) в то же время. Следовательно, мы можем запустить MethodA1/2 в то же время, как MethodB1/2.

Надеется, что это помогает,

 Смежные вопросы

  • Нет связанных вопросов^_^