2011-09-03 19 views
6

Supongamos que tengo la siguiente clase C#Varios hilos que llaman a los mismos objetos funcionan simultáneamente. ¿Puede causar problemas?

class MyClass 
{ 
    private int _i; 
    private object _locker = new object(); 

    public void DoSomething() 
    { 
     var b = 2; 

     // some work that depends on b being 2 

     lock(_locker) 
     { 
      _i = 3; 
     } 

     // some more work 

     b = -1; 

     // some more work 
    } 
} 

Y utilizo esta manera,

//Usage: 

var myobject = new MyClass(); 
new Thread(new ThreadStart(() => myobject.DoSomething())).Start(); 
new Thread(new ThreadStart(() => myobject.DoSomething())).Start(); 

¿Puede la siguiente secuencia pasar?

Thread 1 is halfway through its work. 
Thread 2 just starts. Sets b = 2. 
Thread 1 sets b = -1. 
Thread 2 is confused because it expected b to be 2 but its -1. 

Lo importante es que b es una variable local. ¿Los dos hilos tendrán acceso a la misma instancia de b? Entiendo que para la variable de instancia _i, esto sucederá. De ahí la construcción lock para eso. Pero no estoy seguro de si también debo bloquear las variables locales.

+1

'b' es local y, por lo tanto, exclusivo de cada hilo. –

+1

Si a '_i' solo se le asignan los mismos valores dos veces, ¿por qué no considera mover la asignación en un código no simultáneo antes de iniciar los hilos? (o cuando terminen) –

Respuesta

11

La variable local se colocará en la pila cuando una persona que llama ingrese el método DoSomething(). Cada hilo opera en una pila separada y obtendrá su propia variable local única.

Esta parte de Wikipedia for thread local storage aplica a C# enhebrar así:

En otras palabras, los datos en una variable estática o global es normalmente siempre situado en la misma posición de memoria, cuando se hace referencia por medio de hilos de el mismo proceso Sin embargo, las variables en la pila son locales a los hilos, porque cada hilo tiene su propia pila, que reside en una ubicación de memoria diferente .

+2

Sé en mi ejemplo que la 'b' es un tipo primitivo. Pero supongamos que 'b' es un objeto de alguna clase. Y estoy modificando su propiedad. Ahora que 'b' es un tipo de referencia, ¿seguirá estando en la pila local de cada hilo? Pensé que los objetos de tipo de referencia se almacenaban en la memoria de montón compartida por todos los hilos ... –

+3

@Amith: Si crea el objeto dentro del método, la * referencia de objeto * aún se almacena en la pila mientras que el objeto mismo se asignará en el montón Fundamentalmente, esto no cambia nada ya que cada hilo tiene su propia referencia de objeto a un objeto diferente en el montón. – BrokenGlass

+0

¿Qué pasa si b es un tipo de referencia y se pasó al método como un parámetro de método? – Harindaka

Cuestiones relacionadas