Não, desde que você esteja travando no mesmo objeto. O código recursivo já possui efetivamente o bloqueio e, portanto, pode continuar sem impedimentos.
lock(object) {...}
é uma abreviação para usar a classe Monitor . Como Marc aponta , Monitor
permite a reentrada , portanto, repetidas tentativas de bloquear um objeto no qual o thread atual já possui um bloqueio funcionarão perfeitamente.
Se você começar a travar objetos diferentes , é aí que você deve ter cuidado. Preste especial atenção a:
- Sempre adquira bloqueios em um determinado número de objetos na mesma sequência.
- Sempre libere os bloqueios na sequência inversa de como você os adquire.
Se você quebrar uma dessas regras, estará praticamente garantido que haverá problemas de conflito em algum momento .
Aqui está uma boa página da Web que descreve a sincronização de threads no .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/
Além disso, prenda o menor número possível de objetos ao mesmo tempo. Considere aplicar bloqueios de granulação grossa sempre que possível. A idéia é que, se você pode escrever seu código de forma que exista um gráfico de objetos e adquirir bloqueios na raiz desse gráfico de objetos, faça-o. Isso significa que você tem um bloqueio nesse objeto raiz e, portanto, não precisa se preocupar muito com a sequência na qual você adquire / libera bloqueios.
(Mais uma observação, seu exemplo não é tecnicamente recursivo. Para ser recursivo, Bar()
teria que se chamar, normalmente como parte de uma iteração.)