Нет, пока вы блокируете один и тот же объект. Рекурсивный код эффективно уже имеет блокировку и поэтому может продолжать беспрепятственно.
lock(object) {...}
является сокращением для использования класса Monitor . Поскольку Марк указывает на , Monitor
допускает повторный вход , поэтому повторные попытки заблокировать объект , на котором текущий поток уже имеет Блокировка будет работать нормально.
Если вы начнете блокировать различных объектов, тогда вы должны быть осторожны. Обратите особое внимание на:
- Всегда получать блокировки для определенного количества объектов в одной и той же последовательности.
- Всегда снимайте блокировки в последовательности в обратном порядке в зависимости от того, как вы их приобретаете.
Если вы нарушите любое из этих правил, вы гарантированно получите проблемы тупика в какой-то момент .
Вот одна хорошая веб-страница, описывающая синхронизацию потоков в .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/
Кроме того, блокируйте как можно меньше объектов одновременно. Рассмотрите возможность применения крупнозернистых замков , где это возможно. Идея состоит в том, что если вы можете написать свой код таким образом, что существует граф объектов, и вы можете получить блокировки на корне этого графа объектов, то сделайте это. Это означает, что у вас есть одна блокировка для этого корневого объекта и, следовательно, вам не нужно сильно беспокоиться о последовательности, в которой вы получаете / снимаете блокировки.
(Еще одно замечание, ваш пример не является технически рекурсивным. Чтобы он был рекурсивным, Bar()
должен был бы вызывать сам себя, как правило, как часть итерации.)