2010-09-13 28 views
6

Pregunta sobre variables estáticas en clases estáticas.Propiedades estáticas en clases estáticas

Si tengo una clase estática y establezco el valor de una propiedad, públicamente expuesta, ¿el valor de esta variable se establece para todas las instancias de la clase? Entonces, si el hilo 1 establece el valor de la propiedad en 999, ¿el valor también se establece para el hilo 2 al 999?

Respuesta

11

Sí, lo es. Solo hay una copia de los campos de la clase estática dentro de un Dominio de aplicación.

Sin embargo, debe tener en cuenta la sincronización. Si el hilo 1 establece (escribe en) la variable y el hilo 2 la lee al mismo tiempo, puede obtener resultados inesperados porque es posible que una operación de escritura se divida en múltiples instrucciones del procesador.

Supongamos que establece el valor de long. Este es un valor de 64 bits y escribir implica al menos 2 instrucciones de procesador (en una máquina de 32 bits). Teóricamente es posible que se programe una lectura de la misma variable long entre las dos instrucciones de escritura, lo que lleva a un comportamiento inesperado.

+3

Estrictamente, no hay * instancia * de la clase estática, pero hay una sola copia de cada campo estático –

+0

Tiene razón. Gracias por la información adicional. He actualizado mi respuesta. –

+0

@Marc: Sí, pero ... el OP * dijo * (confusamente), "¿el valor de esta variable está establecido para todas las instancias de la clase?"Así que supongo que el OP en realidad solo tiene una clase regular y está hablando de una propiedad estática. O eso o mal uso de la palabra" instancias ". –

2

Solo para agregar a la discusión (¿por qué no?): Sí, una propiedad static se comparte en todas las instancias de una clase, independientemente del hilo (a menos que el campo de respaldo esté marcado ThreadStatic, ¡eso es!). Pero sí, hay posibles problemas de subprocesamiento múltiple que debe enfrentar al tratar con tales propiedades. Esta es la situación en la que creo que están llegando otros.

consideran este código:

int x = MyClass.StaticProperty; 
MyClass.StaticProperty = x + 1; 

Lo anterior es un ejemplo muy simple de que una condición de carrera podría causar dos hilos para realizar lo que se supone ser dos acciones indivisibles, sino que termina siendo efectivamente una sola acción.

Para ilustrar:

 
Thread 1      Thread 2 
int x = MyClass.StaticProperty;         // Let's say 
           int x = MyClass.StaticProperty; // this is 1. 
MyClass.StaticProperty = x + 1;         // OK, so x is 
           MyClass.StaticProperty = x + 1; // now... 2. 

ve usted el problema? Dos subprocesos pueden leer el valor de la propiedad antes de que le escriba; y el valor que se escribe depende del valor leído, que fue idéntico para ambos hilos.

En simples escenarios como la de arriba, hay una clase práctica proporcionada en el espacio de nombres System.Threading que puede hacer multiproceso lee/escribe bastante sencillo de implementar: Interlocked. Por ejemplo, para incrementar StaticProperty anteriormente de una manera segura para los subprocesos, es posible actualizar MyClass de la siguiente manera:

class MyClass 
    static int _staticProperty; 
    public static int StaticProperty 
    { 
     get { return _staticProperty; } 
    } 

    public static int IncrementProperty() 
    { 
     // increments _staticProperty ATOMICALLY 
     // and returns its previous value 
     return Interlocked.Increment(_staticProperty); 
    } 
} 

En escenarios más complejos (es decir, cuando no se está modificando simplemente los campos numéricos de fricción de una manera directa), es posible que necesite diseñar su propia estrategia de sincronización, la más común de las cuales es tener un objeto de bloqueo designado y simplemente lock en él para cada operación que desee comportarse atómicamente.