No, no siempre que esté bloqueando el mismo objeto. El código recursivo efectivamente ya tiene el bloqueo y, por lo tanto, puede continuar sin obstáculos.
lock(object) {...}
es una abreviatura del uso de la clase Monitor . Como señala Marc , Monitor
permite el reentrada , por lo que los intentos repetidos de bloquear un objeto en el que el hilo actual ya tiene un bloqueo funcionarán bien.
Si comienzas a bloquear diferentes objetos, es cuando debes tener cuidado. Preste especial atención a:
- Adquiera siempre bloqueos en un número determinado de objetos en la misma secuencia.
- Siempre suelte los candados en la secuencia inversa a la forma en que los adquirió.
Si rompes cualquiera de estas reglas, tienes prácticamente la garantía de que tendrás problemas de interbloqueo en algún momento .
Aquí hay una buena página web que describe la sincronización de subprocesos en .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/
Además, bloquee la menor cantidad posible de objetos a la vez. Considere la posibilidad de aplicar cerraduras de grano grueso siempre que sea posible. La idea es que si puede escribir su código de manera que haya un gráfico de objeto y pueda adquirir bloqueos en la raíz de ese gráfico de objeto, hágalo. Esto significa que tiene un bloqueo en ese objeto raíz y, por lo tanto, no tiene que preocuparse tanto por la secuencia en la que adquiere / libera bloqueos.
(Una nota más, su ejemplo no es técnicamente recursivo. Para que sea recursivo, Bar()
debería llamarse a sí mismo, normalmente como parte de una iteración).