2016-11-05 2 views
5

Это то, что я никогда не понимал. Это почти кажется, как взломать, чтобы создать фиктивный объект, который получает lock-е изд, как напримерЗачем нам нужно блокировать и объекты на C#?

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; 
     } 
    } 
} 

из https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx.

Почему бы не разработчики языка сделать так, чтобы

class Account 
{ 
    decimal balance; 

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

будет эквивалентно?

+5

@Sayse Совсем нет, иначе никто не поймет, как использовать «замок» в первую очередь. Причины, по которым необходимо, чтобы параметр 'lock' должен был быть передан параметром, довольно ясны, и вопрос очень важен, если автор не понимает этих причин. – rucamzu

+0

@rucamzu - Я думаю, что неправильно понял вопрос – Sayse

ответ

7

Экземпляр, переданный в lock, служит для идентифицирует критический раздел.

В вашем коде может быть любое количество несвязанных критических разделов, и каждый из них будет блокировать другой объект. Беззаметный оператор lock, подобный тому, который вы предлагаете, не сможет отличить многие критические разделы.

EDIT

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

+0

Да, вы правы, я неправильно понял, и я думаю, что он не понимает, что делает блокировка. Спасибо за комментарий – mybirthname

+0

@mybirthname Нет проблем вообще. И только для записи я нашел ваше объяснение понятным и полезным. – rucamzu

0

Я думаю, что замешательство заключается в том, что делает ключевое слово блокировки. Это не говорит только 1 поток может войти в этот раздел кода, но он говорит 2 вещи:

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

То, что вы предлагаете, будет делать только 1-й, но не тот и другой. Посмотрите на этом примере:

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

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

     // more code here but no locking necessary... 

     lock(thisLock) 
     { 
      // only one thread can enter here who has thisLock 
     } 

     lock (thisLock2) 
     { 
      // If T1 (thread1) is working with thisLock, T2 can come here since it has nothing to do 
      // with thisLock. 
     } 
    } 

    public void AnotherOperation() 
    { 
     lock (thisLock) 
     { 
      // code here... 
     } 
    } 

    public void YetAnotherOperation() 
    { 
     lock (thisLock) 
     { 
      // code here... 
     } 
    } 
} 

Когда нить, скажет T1, делают отборочную часть с первым замком, все остальные секции класса с замком (thisLock) не допускается ввод любого другого потока, а также , Тем не менее, часть с этимLock2 разрешена для ввода другими потоками.

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

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