2012-02-08 14 views
5

Si tengo¿Funcionan los bloqueos estáticos en diferentes clases de niños?

abstract class Parent 
{ 
    static object staticLock = new object(); 

    public void Method1() 
    { 
     lock(staticLock) 
     { 
      Method2(); 
     } 
    } 

    protected abstract Method2(); 
} 

class Child1 : Parent 
{ 
    protected override Method2() 
    { 
      // Do something ... 
    } 
} 

class Child2 : Parent 
{ 
    protected override Method2() 
    { 
      // Do something else ... 
    } 
} 

Will llamadas a new Child1().Method1()new Child2().Method1() y utilizar la misma cerradura?

+0

Y staticLock es "privado" (predeterminado para miembros http://msdn.microsoft.com/en-us/library/ms173121.aspx), por lo que no se puede acceder por clases secundarias. –

+0

@AlexeiLevenkov Solo quiero garantizar que solo se llame a un 'Método2' en un instante, no necesito que las clases secundarias accedan a él. –

+1

@JohnSaunders: No te estoy siguiendo. La idea aquí es tener un método * público * que * no sea invalidable * que garantice que * las personas que llaman * siempre tomen la cerradura. De esta forma, los autores de las clases derivadas pueden implementar Method2 sin tener que recordar "oh sí, tengo que cerrar aquí". Este patrón elimina un tipo de error pero, por supuesto, produce oportunidades para otro; ahora los autores de esas clases derivadas deben saber que se toma el bloqueo de clase principal y no provocar un punto muerto en él. –

Respuesta

15

Sí. Una clase derivada no obtiene una nueva copia de los datos estáticos de la clase base.

Sin embargo, este no es el caso con las clases genéricas . Si dices:

class Base<T> 
{ 
    protected static object sync = new object(); 
    ... 
} 

class Derived1 : Base<int> { ... } 
class Derived2 : Base<int> { ... } 
class Derived3 : Base<string> { ... } 
class Derived4 : Base<string> { ... } 
class Derived5 : Base<object> { ... } 
class Derived6 : Base<object> { ... } 

las instancias de Derived1 y Derived2 tienen el mismo objeto de sincronización. Las instancias de Derived3 y Derived4 tienen el mismo objeto de sincronización. Las instancias de Derived5 y Derived6 tienen el mismo objeto de sincronización. Pero los tres objetos de sincronización son todos objetos diferentes.

+2

Eric, dado que el código genérico está jodido una vez para todos los tipos de referencia, ¿eso significa que 'clase Derived4: Base {...}' compartiría el mismo objeto de sincronización con 'Derived3'? – phoog

+4

@phoog: Buena pregunta. No; las diferentes construcciones de un tipo genérico son * tipos diferentes *. 'Base ' y 'Base ' son tipos diferentes, por lo que 'Base .sync' y' Base .sync' son campos diferentes.El hecho de que como detalle de implementación, la fluctuación jitirá * los * métodos * de 'Base ' y 'Base ' una vez y reutilizar el estado jitted no cambia en absoluto el hecho de que son * tipos diferentes *. –

+0

Gracias Eric, la idea de que 'Base .sync' y' Base .sync' podría ser el mismo campo fue bastante inquietante. – phoog

2

Sí, en general, lock en static objetos protegen los datos de todas las instancias de su clase.

De MSDN:

mejor práctica consiste en definir un objeto privado para bloquear en, o una variable de objeto estático privado para proteger los datos comunes a todas las instancias.

2

Para agregar a la respuesta de ken2k: [Sí] ... a menos que esté marcado como [ThreadStatic] (que obviamente no es el caso aquí).

+0

No lo sabía. Muy importante para otro problema con el que estaba lidiando. –

+2

De hecho, un bloqueo estático de hilo preferiría derrotar el propósito de tener el bloqueo en primer lugar. –

Cuestiones relacionadas