Оператор блокировки НЕ "блокирует код" или любой ресурс, который находится между фигурными скобками, как таковой.
Я считаю, что лучше всего понимать блокировку с точки зрения потока (в конце концов, в сценариях с потоками нужно учитывать блокировку).
Учитывая ваш пример кода
10 locker = new object();
11 lock (locker)
12 {
...
15 }
Когда поток X достигает строки 10, создается новый объект, а в строке 11 устанавливается блокировка для объекта. Поток X продолжает выполнять любой код внутри блока.
Теперь, пока поток X находится в середине нашего блока, поток Y достигает строки 10. И вот, создается новый объект, и, поскольку он создается потоком Y, в настоящее время блокировка этого объекта не осуществляется. Поэтому, когда поток Y достигает 11, он успешно получает блокировку объекта и продолжает выполнять блок одновременно с потоком X.
Это ситуация, которую замок должен был предотвратить. Так что делать?
Сделать шкафчик общим объектом .
01 static object locker = new object();
...
11 lock (locker)
12 {
...
15 }
Теперь, когда поток X достигнет строки 11, он получит блокировку и начнет выполнение блока. Когда поток Y достигает строки 11, он пытается получить блокировку для того же объекта, что и поток X. Поскольку этот объект уже заблокирован, поток Y будет ждать, пока блокировка не будет снята. Таким образом предотвращая одновременное выполнение блока кода, тем самым защищая любые ресурсы, используемые этим кодом, для одновременного доступа.
Примечание: если другие части вашей системы должны быть сериализованы вокруг одних и тех же ресурсов, они все должны попытаться заблокировать один и тот же объект общей блокировки.