Почему монитор должен быть получен до вызова Monitor.Wait () - PullRequest
2 голосов
/ 21 января 2011

Если поток вызывает Monitor.Wait(lockObj) для объекта блокировки, которым он в данный момент не владеет, будет выброшено SyncronizationLockException.

Я не понимаю смысл этого?Если поток владеет блокировкой и, таким образом, может успешно вызвать Monitor.Wait(), он просто все равно немедленно снимет блокировку.Почему поток не может просто ждать блокировки, которой он в данный момент не владеет?


Обновление

Я решил добавить немного больше объяснений к моему вопросу.

Из того, что я понимаю, Wait просто помещает текущий поток в очередь ожидания мониторов и снимает блокировку.Позже импульс или импульс все перемещает один или все потоки в очереди ожидания в очередь готовности.Всякий раз, когда монитор освобождается, следующей (если таковой имеется) поток в очереди готовности получает блокировку.

Так почему же ожидание не может просто добавить поток в очередь ожидания?Почему для этого нужно получить блокировку?Есть ли физическая причина для этого или просто то, что Microsoft разработала этот класс, чтобы заставить вас правильно его использовать?

Теперь, когда я думаю об этом, я полагаю, что что-то стоит в очереди ожидания монитора или перемещаетготовая очередь действительно манипулирует монитором.Было бы разумно, чтобы для этого вам понадобился собственный монитор.Это правильный способ думать об этом?

Мы многопоточны, мой мозг труден!

Ответы [ 3 ]

1 голос
/ 19 марта 2012

Monitor.Wait используется для снятия блокировки и последующего ее восстановления атомарным способом . Ни один другой механизм синхронизации в BCL не претендует на славу. Очевидно, Wait не может восстановить блокировку, если она еще не существует. Вот почему исключение выдается.

Тот факт, что Wait возвращает существующую блокировку, является очень мощным механизмом. Именно эта фундаментальная уникальность поведения позволяет использовать его для создания всех других механизмов синхронизации в BCL.

1 голос
/ 21 января 2011

Смысл Monitor.Wait в том, чтобы дать другим нитям возможность захватить ваш замок.

Если вы не владеете замком, в этом нет никакого смысла; другие потоки уже могут захватить блокировку.
(Если какой-то другой поток уже не владеет блокировкой, в этом случае вызов Wait испортит этот поток)

0 голосов
/ 22 января 2011

Вызов Monitor.Wait без блокировки в большинстве случаев привел бы к недетерминированной ошибке.То же самое, если вы вызываете Monitor.Wait сразу после получения блокировки и без установки каких-либо общих переменных между получением блокировки и вызовом Monitor.Wait.

В частности - если у вас нет блокировки, вы можетеНикогда не убедитесь, что сопровождающий Monitor.Pulse не был выполнен до того, как вы ввели Monitor.Wait.Подумайте о ситуации, когда операционная система приостановила поток A непосредственно перед вызовом Monitor.Wait и возобновила поток B, который выполняет Monitor.Pulse после выполнения некоторых вычислений.Все общие переменные убеждают поток B в том, что A ожидает, но это просто не соответствует действительности.И поток A не может прекратить выполнение Monitor.Wait в этот момент.

Также - вас может заинтересовать идея семафоров http://en.wikipedia.org/wiki/Semaphore_(programming).Вы можете подождать и подать сигнал без идеи их приобретения.Это потому, что они держат в себе государство.Поэтому, если вы подадите сигнал первым, ожидание не заблокируется.

...