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