Большинство других ответов относятся к вашему примеру кода, поэтому я постараюсь ответить на ваш вопрос в заголовке.
Замок на самом деле просто знак. Тот, у кого есть знак, может выйти на сцену, так сказать. Таким образом, объект, на который вы блокируете, не имеет явного соединения с ресурсом, вокруг которого вы пытаетесь синхронизироваться. Пока все читатели / писатели согласны с одним и тем же маркером, это может быть что угодно.
При попытке заблокировать объект (т. Е. Путем вызова Monitor.Enter
объекта) среда выполнения проверяет, удерживается ли блокировка потоком. В этом случае поток, пытающийся заблокировать, приостанавливается, в противном случае он получает блокировку и переходит к выполнению.
Когда поток, удерживающий блокировку, выходит из области блокировки (то есть вызывает Monitor.Exit
), блокировка снимается, и любые ожидающие потоки могут теперь получить блокировку.
Наконец, несколько вещей, которые следует иметь в виду в отношении замков:
- Блокировка столько, сколько вам нужно, но не дольше.
- Если вы используете
Monitor.Enter/Exit
вместо ключевого слова lock
, обязательно разместите вызов Exit
в блоке finally
, чтобы блокировка снималась даже в случае исключения.
- Предоставление объекта для блокировки усложняет получение представления о том, кто и когда блокируется. Идеально синхронизированные операции должны быть инкапсулированы.