2009-12-09 15 views
16

Duplicar posible:
Difference between lock(locker) and lock(variable_which_I_am_using)¿Por qué se realizan bloqueos en objetos separados?

En todos los ejemplos de código "compatibles con el proceso" que he visto, que se traben en un objeto ficticio separado. ¿Por qué no se pueden realizar bloqueos directamente en los datos en cuestión?

+0

gran pregunta, este fue mi primer pensamiento también. – Russell

+1

Con el fin de ayudar a las personas a encontrar la respuesta que están buscando, esta pregunta no debe cerrarse. @Bill, la llamada pregunta duplicada exacta está torpemente titulada y redactada y no establece claramente la pregunta fundamental a diferencia de esta pregunta. Creo que es mucho más probable que esta pregunta llame la atención en las búsquedas. Por lo tanto, he votado para reabrir. – Ash

Respuesta

18

El bloqueo en un objeto dummy separado private le garantiza que nadie más está bloqueando ese objeto.

Si bloquea los datos y ese mismo dato es visible desde afuera, pierde esa garantía. Por ejemplo:

public class MyObject 
{ 
    public void SharedMethod() 
    { 
     lock (this) 
     { 
      // Do stuff 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     MyObject o = new MyObject(); 

     lock (o) 
     { 
      new Thread(() => 
      { 
       // Gets blocked 2s because of external lock 
       o.SharedMethod(); 
      }).Start(); 

      Thread.Sleep(2000); 
     } 
    } 
} 
+0

Buen ejemplo del problema. – RichardOD

+0

Creo que lo entiendo. Si tiene un objeto ficticio separado, al bloquear un objeto que desea usar, ¿no le está impidiendo hacer nada? – RCIX

+0

Quiero decir, cuando intentas llamar a un método en ese objeto que necesita marcar algo. – RCIX

2

Hay algunas cosas buenas sobre esto en el blog de Eric Gunnerson. Ver here y here.

8

Jeff Richter (autor de CLR Via C#) explica por qué en este artículo en Safe Thread Synchronization.

Específicamente, en ese artículo la pregunta "Por qué la gran idea no es tan buena" responde a su pregunta.

En realidad es un capítulo del libro CLR Via C#.

En resumen, tener un objeto privado como objeto "synclock" permite a su clase encapsular y controlar cualquier bloqueo que su clase necesite. Por lo tanto, independientemente de cuántos clientes usen su clase, el bloqueo se realiza de manera consistente y correcta.

+0

+1. Iba a señalar su libro, ¡pero este artículo es efectivamente el mismo! – RichardOD

+0

Si un objeto necesita ser bloqueado durante ciertas operaciones, y si el código externo puede necesitar realizar dos o más operaciones sin que se libere el bloqueo entre ellas, el objeto debe exponer el bloqueo o los métodos para adquirirlo y liberarlo. Al exponer ninguno de ellos, simplemente hará imposible que el código externo haga lo que debe hacer. – supercat

Cuestiones relacionadas