net - for thread c#
¿Por qué Lock''ing en el mismo objeto no causa un punto muerto? (4)
Posible duplicado:
Reentrantes bloqueos en C #
Si escribo un código como este:
class Program {
static void Main(string[] args) {
Foo();
Console.ReadLine();
}
static void Foo() {
lock(_lock) {
Console.WriteLine("Foo");
Bar();
}
}
static void Bar() {
lock(_lock) {
Console.WriteLine("Bar");
}
}
private static readonly object _lock = new object();
}
Me sale como salida:
Foo
Bar
Esperaba que esto se estancara, porque Foo adquiere un candado y luego espera que Bar adquiera el candado. Pero esto no sucede.
¿El mecanismo de bloqueo simplemente lo permite porque el código se ejecuta en el mismo hilo?
La instrucción de lock
es más inteligente que eso, y está diseñada para evitar esto. El bloqueo es "propiedad" de la secuencia una vez que entra en ella, de modo que cada vez que llegue a otra instrucción de lock
que bloquee el mismo objeto se dará cuenta de que ya tiene acceso a ese bloqueo.
Para el mismo hilo, un bloqueo siempre es reentrant , por lo que el hilo puede bloquear un objeto con la frecuencia que desee.
Porque solo tienes un hilo aquí.
lock
es un atajo para
bool lockWasTaken = false;
var temp = obj;
try {
Monitor.Enter(temp, ref lockWasTaken);
// your thread safe code
}
finally { if (lockWasTaken) Monitor.Exit(temp); }
Monitor.Enter el monitor en el objeto pasado como el parámetro. Si otro hilo ha ejecutado un Enter en el objeto pero aún no ha ejecutado la salida correspondiente, el hilo actual se bloqueará hasta que el otro hilo libere el objeto. Es legal que el mismo hilo invoque Enter más de una vez sin bloquearlo ; sin embargo, se debe invocar un número igual de llamadas de salida antes de que se desbloqueen otros subprocesos que esperan en el objeto.
Una palabra: bloqueo de reentrada. Si un hilo ya ha adquirido un bloqueo, no espera si quiere adquirir el bloqueo nuevamente. Esto es muy necesario, de lo contrario podría haber convertido simples funciones recursivas en una pesadilla.