2012-05-17 51 views
5

espero que el siguiente código a un punto muerto cuando Claro intenta bloquear en el mismo objeto que se acumulan ya ha bloqueado:¿Por qué este código no se bloquea?

void Main() 
{ 
    (new SiteMap()).Build(); 
} 

class SiteMap 
{ 
    private readonly object _lock = new object(); 

    public void Build() 
    { 
     lock (_lock) 
     { 
      Clear(); 

      Console.WriteLine("Build"); 
     } 
    } 

    public void Clear() 
    { 
     lock (_lock) 
     { 
      Console.WriteLine("Clear"); 
     } 
    } 
} 

Salida:

Claro

Construir

Edición 1

Gracias a todos por sus respuestas.

Si añado una llamada a construir dentro de la cerradura de Clear (manteniendo el resto del código de la misma):

public void Clear() 
{ 
    lock (_lock) 
    { 
     Build(); 

     Console.WriteLine("Clear"); 
    } 
} 

¿Se produce un interbloqueo (o al menos eso es lo que pienso, accidentes Pad LINQ)

De acuerdo con sus respuestas, esto no debería suceder, porque sigue siendo el mismo hilo.

Gracias!

+1

Consulte http://www.albahari.com/threading/part2.aspx, bajo "Bloqueo anidado". –

Respuesta

8

En C#, un hilo que tenga un bloqueo puede ingresar al mismo bloqueo sin bloqueo.

La instrucción lock, así como la Monitor class en la que está construida, es reentrant en .NET.


Editar en respuesta a tu edición:

Cuando se agrega el llamado a Build dentro clara, el código no punto muerto - que está llamando a sí mismo de forma recursiva. No es bloqueo, sino que más bien se ejecuta siempre (hasta que, finalmente, te encuentras con un StackOverflowException), porque Build llamadas Clear que se pide de nuevo que se pide BuildClear, etc ....

+0

En cuanto a mi edición, realmente no sé cómo no lo vi. ¡Gracias por ambas respuestas! – stacker

4

No lo haré porque se llama a clear en el mismo hilo que ya aplicó el bloqueo.

5

La documentación para lock dice:

Si otro hilo intenta ingresar un código bloqueado, esperará (bloqueará) hasta que se libere el objeto.

La palabra clave es "otra". Un hilo no se bloquea a sí mismo, solo otros hilos. Si otro hilo hubiera sido dueño del bloqueo, entonces lock se bloquearía.

Esto ahorra muchos dolores de cabeza.

Cuestiones relacionadas