Я знаю, как использовать блокировки в своем приложении, но еще мало чего не понимаю о блокировке (BTW - я знаю, что оператор блокировки - это просто сокращенная запись для работы с типом класса Monitor).
От http://msdn.microsoft.com/en-us/library/ms173179.aspx:
public class TestThreading
{
private System.Object lockThis = new System.Object();
public void Function()
{
lock (lockThis)
{
// Access thread-sensitive resources.
}
}
}
Аргумент, предоставленный ключевому слову блокировки, должен быть объектом, основанным на ссылке type, и используется для определения области блокировки. В приведенном выше примере область блокировки ограничена этой функцией, поскольку ссылки на блокировку объекта не существуют вне функции. Если такая ссылка действительно существует, область блокировки будет распространяться на этот объект.
a) Я не понимаю, как lockThis определяет область блокировки. Область блокировки - это весь код между блокировкой (lockThis) { и смежным }, так что именно это означает, что "область блокировки будет распространяться на этот объект"?
b) Что означает термин "блокировка" для объекта lockThis? Просто мы используем ссылку на lockThis, чтобы заблокировать область кода? Таким образом, этот термин не предполагает, что мы заблокировали lockThis объект?
спасибо
Отвечая Дэвиду Мортону:
Извиняюсь, если мой ответ немного длинный, но я не мог придумать другого способа рассказать о моих вопросах и по-прежнему быть несколько последовательным:
- Объем блокировки в этой ситуации - это отдельный экземпляр самого класса. Это противоречит пересечению всего экземпляра конкретного класса. Вы можете заблокировать все блокированные экземпляры TestThreading, сделав lockThis static. То, что подразумевается под "областью" блокировки: применимо ли оно к одному экземпляру или применимо ко всем экземплярам определенного типа.
Другие объекты все равно могут получить доступ к lockThis из другого потока, но они не смогут обрабатывать код, окруженный блокировкой на этом объекте.
Если мы вызываем код, окруженный блокировкой (расположенный внутри TestThreading.Function) C, то, поскольку TestThreading.Function не является статическим, каждый экземпляр TestThreading имеет свою собственную копию C. Но если TestThreading.Function был статичным, то все экземпляры TestThreading будут иметь одну и ту же копию C. В качестве аналогии, если C является комнатой, и если TestThreading.Function не является статичным, то каждый экземпляр TestThreading будет иметь свою собственную C комнату, но если функция была статической, то все экземпляры TestThreading будут иметь одну и ту же C комнату.
Следуя этой аналогии, я интерпретирую lockThis как ключ к комнате C. Если lockThis является статическим, и если TestThreading.Function не является статичным, то все экземпляры TestThreading будут использовать один и тот же ключ для входа в собственные комнаты C.
-
Таким образом, я не вижу никакого значения в lockThis, статическом или нет, поскольку в каждом случае каждый экземпляр TestThreading будет использовать lockThis для входа в свою комнату C (предполагая, что TestThreading.Function не является статическим). Таким образом, следуя этой логике, не должна ли область блокировки быть индивидуальным экземпляром класса (предполагая, что TestThreading.Function не является статическим)?
-
Точно так же я не вижу никакого значения в lockThis, являющемся закрытым или общедоступным, так как снова экземпляр TestThreading будет использовать lockThis для ввода собственной комнаты C (предполагая, что TestThreading.Function не является статическим)
Второй ответ Дэвиду Мортону
В ответ на ваш ответ: есть значение. Если TestThreading.Function статична, то lockThis должен быть статичным, иначе TestThreading.Function не может получить доступ к lockThis вообще.
Я не уверен, что вы подразумеваете под TestThreading. Функция не может получить доступ к lockThis?! Снова предположим, что мы вызываем код, окруженный блокировкой (находящейся внутри TestThreading.Function) C. Если TestThreading.Function статична и, следовательно, существует только одна комната, но lockThis не статична, и если мы имеем следующее определение:
public class TestThreading
{
private System.Object lockThis = new System.Object();
public static void Function()
{
lock (new TestThreading().lockThis)
{
// Access thread-sensitive resources.
}
}
}
тогда всякий раз, когда какой-либо поток будет иметь доступ к комнате C, он будет использовать новый ключ. Таким образом, если 100 потоков обратились к комнате C, то такая же комната была бы открыта с использованием 100 разных ключей?! Таким образом, код действительно работает, он просто не имеет большого смысла, поскольку между потоками не будет никакой синхронизации!
Объем блокировки в этой ситуации - это отдельный экземпляр самого класса. Это противоречит пересечению всего экземпляра конкретного класса. Вы можете заблокировать все блокировки экземпляров TestThreading, сделав lockThis static.
Я был смущен термином scope lock, так как Ive интерпретировал его как: если lockThis был статичным, то все экземпляры TestThread будут иметь одну и ту же комнату (aka lock), хотя TestThread.Function не является статичным. Предполагая, что я правильно понял это сейчас, тогда термин блокировка относится к ключу (таким образом, блокировка не относится к комнате?!), используемой для открытия дверей?
Таким образом, если мы предположим, что lockThis является статическим и TestThread.Function не является статическим, то область ключа/блокировки - это все экземпляры TestThread, что означает, что все экземпляры TestThread используют один и тот же ключ, и поэтому, когда один экземпляр TestThread открывает дверь в свою комнату с помощью этого ключа, другие экземпляры не смогут открыть двери в свои комнаты, пока первый экземпляр не выпустит этот ключ?
Третий ответ Дэвиду Мортону
Нет, если функция статична, то все экземпляры TestThread будут использовать одну и ту же комнату, если lockThis является статическим, тогда все экземпляры TestThread будут использовать один и тот же ключ.
Согласны ли вы с тем, что слово-блокировка, используемая в области предложения блокировки, по крайней мере, в некотором смысле относится к ключу (ключ является экземпляром lockThis)?
Комната - это код, который выполняется внутри замка, а не самого объекта lockThis, который просто является ключом.
[Защитный режим включен] То, что Ive сказал в моем последнем ответе.;) [Защитный режим выключен]