2010-01-13 18 views
68

¿Qué significa este código de Java? ¿Obtendrá bloqueo en todos los objetos de MyClass?Bloque sincronizado de Java para .class

synchronized(MyClass.class) { 
    //is all objects of MyClass are thread-safe now ?? 
} 

Y cómo el código anterior se diferencia de éste:

synchronized(this) { 
    //is all objects of MyClass are thread-safe now ?? 
} 
+0

Relacionado: http://stackoverflow.com/questions/437620/java-synchronized-methods-lock-on-object-or-class – finnw

Respuesta

111

El fragmento synchronized(X.class) utiliza la instancia de clase como monitor. Como solo hay una instancia de clase (el objeto que representa los metadatos de clase en tiempo de ejecución), un hilo puede estar en este bloque.

Con synchronized(this) el bloque está protegido por la instancia. Para cada instancia, solo un hilo puede ingresar al bloque.

synchronized(X.class) se utiliza para asegurarse de que hay exactamente un subproceso en el bloque. synchronized(this) asegura que hay exactamente un hilo por instancia. Si esto hace que el código real en el bloque sea seguro para subprocesos, depende de la implementación. Si mutee solo el estado de la instancia synchronized(this) es suficiente.

+6

"como muchos hilos pueden entrar en el bloque ya que hay una instancia" implica que la segunda forma actúa como un semáforo que no es verdadero. Debería decir algo como: "sincronizado (esto) asegura que solo un hilo pueda ingresar al bloque para una instancia determinada de la clase". – liwp

+0

Corregido. Tenía la intención de decir eso. –

+1

¿Cuál es la instancia de clase frente a la instancia? –

18

No, el primero será obtener un bloqueo en la definición de clase de MyClass, no todas las instancias de la misma. Sin embargo, si se usa en una instancia, esto efectivamente bloqueará todas las demás instancias, ya que comparten una única definición de clase.

El segundo obtendrá un bloqueo en la instancia actual solamente.

En cuanto a si esto hace que sus objetos sean seguros, esta es una pregunta mucho más compleja, ¡necesitaríamos ver su código!

+1

sí, MyClass.class podría ser cualquier variable estática y tener el mismo efecto. – pstanton

64

Para añadir a las otras respuestas:

static void myMethod() { 
    synchronized(MyClass.class) { 
    //code 
    } 
} 

es equivalente a

static synchronized void myMethod() { 
    //code 
} 

y

void myMethod() { 
    synchronized(this) { 
    //code 
    } 
} 

es equivalente a

synchronized void myMethod() { 
    //code 
} 
+9

Me llevó una segunda lectura captar que los dos primeros ejemplos tienen la palabra clave "estática". Solo lo mencioné a otros que pudieron haberlo visto y lo perdieron. Sin la palabra clave estática, los primeros dos ejemplos no serían lo mismo. – kurtzbot

Cuestiones relacionadas