2011-07-31 6 views

Respuesta

18

Podría haber una gran diferencia. La mayor diferencia entre los dos es que el primer ejemplo usa un único objeto para bloquear (de ahí la palabra clave static) mientras que la palabra clave this en el segundo ejemplo implica el bloqueo de una instancia. Por lo tanto, podría haber una gran diferencia desde la perspectiva del rendimiento e incluso desde la perspectiva de la corrección, pero eso depende del código dentro del bloqueo.

Cuando todo lo que necesita es sincronizar el acceso a los campos de nivel de instancia, no debe usar la palabra clave static, ya que sincronizará el código en sí, en lugar de los datos (lo que podría causar un golpe de rendimiento innecesario). Por supuesto, si los datos en sí son estáticos (datos de nivel de clase en lugar de datos de nivel de instancia), debe usar la palabra clave static. Por otro lado, cuando usa la palabra clave this para bloquear, mientras está accediendo a recursos compartidos/estáticos, tendrá (por supuesto) un problema de corrección, ya que la sincronización es por instancia y la instancia múltiple aún podrá acceder a los datos compartidos al mismo tiempo.

Y hay otro problema, pero la diferencia es mucho menor que para las diferencias anotadas anteriormente. El primer ejemplo utiliza un objeto declarado de manera privada para cerrarse, mientras que el otro usa el puntero this, que es la referencia al objeto del método de instancia en sí. Debido a que esta referencia es públicamente accesible para otros objetos, es posible que se bloqueen, lo que podría causar bloqueos en circunstancias excepcionales.Si eres un desarrollador de aplicaciones, no me preocuparía mucho por esto (siempre y cuando no bloquees cosas como System.String o System.Type), pero si eres un desarrollador de frameworks, no deberías usar lock(this), ya que no hay forma de saber de qué manera los desarrolladores de aplicaciones (ab) usarán su código.

8

Es casi siempre preferible para bloquear en un objeto de sólo lectura privada.

La diferencia es que this es generalmente visible en el código externo, que puede tomar un bloqueo en ella, es decir -

var obj = new YourClass(); 
lock(obj) 
{ 
    ... 
} 

... en cuyo caso cualquier intento interior de YourClass-lock (this) bloquearía.

1

Porque no desea que se acceda al bloqueo desde el exterior del objeto.

Si utiliza bloqueo (este) se puede obtener un callejón sin salida:

void blah() { 
    lock(this); 
    sleep(200); 
} 

//Some other block of code 

MyObject a; 
foreach(Mythread m in threads) 
{ 
    lock(a); 
    m.Call(a.blah); //Not the best syntax, but you get the idea. 
} 

Si se mantiene el bloqueo dentro del objeto no sería un punto muerto.

Cuestiones relacionadas