Несколько блоков кода заблокированы одним и тем же объектом - PullRequest
8 голосов
/ 20 октября 2011

Если у меня что-то вроде этого:

private readonly object objectLock = new object();

public void MethodA()
{
    lock(objectLock)
    {
      //do something
    }
}

public void MethodB()
{
    lock(objectLock)
    {
      //do something
    }
}

Если у меня 2 потока, и оба входят одновременно, 1-й поток вызывает MethodA и второй метод B. В зависимости от того, что получится первым и заблокирует objectLock,Я предполагаю, что другой поток сидит там, ожидая, пока objectLock больше не заблокирован.

Ответы [ 5 ]

5 голосов
/ 20 октября 2011

Это правильно.

Однако блокировка объекта не блокируется (и не объект), а блоки кода.

Подумайте об объекте, который передаетсяключевое слово lock в качестве ключа, открывающего несколько дверей, но одновременно предоставляющего доступ только к одной комнате.

5 голосов
/ 20 октября 2011

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

(слегка оффтоп)Я бы посоветовал не блокировать целые методы, если они делают что-то нетривиальное.Старайтесь, чтобы раздел «блокировки» кода был как можно меньше и быстрее.

1 голос
/ 20 октября 2011

Ты абсолютно прав!Но будьте осторожны с замками.Блокировки, возможно, сделают вашу программу поточно-ориентированной (то есть, при параллельном доступе не будет ошибок), но потребуется гораздо больше усилий, чтобы ваша программа получала реальные преимущества от работы в многоядерной системе.

0 голосов
/ 20 октября 2011

Ты прав.Если это нежелательно, то учтите, что:

lock(objectLock)
{
  //do something
}

Эквивалентно:

Monitor.Enter(objectLock);
try
{
  //do something
}
finally
{
  Monitor.Exit(objectLock);
}

Вы можете заменить это на:

if(Monitor.TryEnter(objectLock, 250))//Don't wait more than 250ms
{
  try
  {
    //do something
  }
  finally
  {
    Monitor.Exit(objectLock);
  }
}
else
{
  //fallback code
}

Это такжеСтоит посмотреть на перегрузки TryEnter() и других объектов синхронизации, таких как ReaderWriterLockSlim.

0 голосов
/ 20 октября 2011

да, вы правы, так как Monitor.Enter и Monitor.Exit вызывается для одного объекта objectLock за сценой. помните, что блок кода, который синхронизируется, не objectLock.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...