2010-04-12 11 views
7

que tienen una clase que contiene un campo booleano como éste:multihilo y booleanos

public class MyClass 
{ 
    private bool boolVal; 
    public bool BoolVal 
    { 
     get { return boolVal; } 
     set { boolVal = value; } 
    } 
} 

El campo puede ser leído y escrito de muchos hilos utilizando la propiedad. Mi pregunta es si debería cercar el getter y el setter con un enunciado de bloqueo. ¿O debería simplemente usar la palabra clave volátil y guardar el bloqueo? ¿O debería ignorar totalmente el multihilo ya que obtener y establecer valores booleanos atómicos?

cordiales,

Respuesta

9

Existen varios problemas aquí.

El primero simple. Sí, leer y escribir una variable booleana es una operación atómica. (aclaración: Lo que quiero decir es que leen y escriben operaciones por sí mismos son operaciones atómicas para booleanos, no leer y escrito, que, por supuesto, genera dos operaciones, que en conjunto no serán atómica)

Sin embargo, a menos que tome medidas adicionales, el compilador podría optimizar dicha lectura y escritura, o mover las operaciones, lo que podría hacer que su código opere de manera diferente a lo que pretende.

Marcar el campo como volatile significa que las operaciones no se optimizarán, la directiva básicamente dice que el compilador nunca debe asumir que el valor en este campo es el mismo que el anterior, incluso si acaba de leerlo en el instrucción previa.

Sin embargo, en máquinas multinúcleo y multicpu, diferentes núcleos y cpus pueden tener un valor diferente para el campo en su caché, y así agregar una cláusula lock { }, o cualquier otra cosa que obligue a una barrera de memoria. Esto asegurará que el valor del campo sea constante en todos los núcleos. Además, las lecturas y escrituras no se moverán más allá de una barrera de memoria en el código, lo que significa que tiene la capacidad de predecir dónde ocurren las operaciones.

Así que si sospecha, o sabe, que este campo se escribirá y leerá desde múltiples hilos, definitivamente agregaría bloqueo y volatilidad a la mezcla.

Tenga en cuenta que no soy un experto en multihebra, soy capaz de defenderme, pero normalmente programo a la defensiva. Podría (supongo que es muy probable) que pueda implementar algo que no use un bloqueo (hay muchas construcciones sin bloqueo), pero lamentablemente no tengo experiencia suficiente en este tema para manejar esas cosas. Por lo tanto, mi consejo es agregar una cláusula lock y una directiva volatile.

+0

"leer y escribir una variable booleana es una operación atómica". ... esto no es verdad. Algo tan simple como "boolean a = b" genera 2 instrucciones JVM. – sgp15

+0

Lo siento, * las operaciones de * lectura * y * escritura * por sí mismas son operaciones atómicas para booleanos, leer y escribir, es dos. Esto es cierto para ** .NET ** y Java. –

2

volátiles por sí sola no es suficiente y sirve para un propósito diferente, la cerradura debe estar bien, pero al final depende de si alguien va a establecer boolval en MiClase vacación por sí misma, quién sabe, puede que tenga un hilo de trabajador girando allí. También depende y cómo está usando boolVal internamente. Es posible que también necesites protección en otro lugar. Si me preguntas, si no estás SEGURO de que vas a usar MyClass en más de un hilo, entonces ni siquiera vale la pena pensar en ello.

P.S. es posible que también desee leer this section