¿El siguiente código dará como resultado un interbloqueo al usar C # en .NET?
class MyClass
{
private object lockObj = new object();
public void Foo()
{
lock(lockObj)
{
Bar();
}
}
public void Bar()
{
lock(lockObj)
{
// Do something
}
}
}
Respuestas:
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:
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).fuente
Bueno,
Monitor
permite la reentrada, por lo que no puede bloquearse usted mismo ...fuente
Si un hilo ya está bloqueado, entonces no se bloqueará. El marco .Net garantiza esto. Solo debe asegurarse de que dos subprocesos no intenten adquirir los mismos dos bloqueos fuera de secuencia mediante cualquier ruta de código.
El mismo hilo puede adquirir el mismo candado varias veces, pero debes asegurarte de liberar el candado la misma cantidad de veces que lo adquieres. Por supuesto, siempre que utilice la palabra clave "bloquear" para lograr esto, sucede automáticamente.
fuente
No, este código no tendrá bloqueos muertos. Si realmente desea crear un punto muerto, el más simple requiere al menos 2 recursos. Considere el escenario del perro y los huesos. 1. Un perro tiene control total sobre 1 hueso, por lo que cualquier otro perro tiene que esperar. 2. Se requieren 2 perros con 2 huesos como mínimo para crear un punto muerto cuando bloquean sus huesos respectivamente y buscan otros huesos también.
.. así sucesivamente n perros y m huesos y provocan interbloqueos más sofisticados.
fuente