2010-01-13 7 views
68

Que signifie ce code java? Verrouillera-t-il tous les objets de MyClass?Java Synchronized Block for .class

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

Et comment le code ci-dessus diffère de celui-ci:

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

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

Répondre

111

L'extrait synchronized(X.class) utilise l'instance de classe en tant que moniteur. Comme il n'y a qu'une instance de classe (l'objet représentant les métadonnées de classe à l'exécution), un thread peut être dans ce bloc. Avec le synchronized(this), le bloc est protégé par l'instance. Pour chaque instance, un seul thread peut entrer dans le bloc.

synchronized(X.class) est utilisé pour s'assurer qu'il y a exactement un thread dans le bloc. synchronized(this) garantit qu'il y a exactement un thread par instance. Si cela rend le code réel dans le bloc thread-safe dépend de l'implémentation. Si muter seulement l'état de l'instance synchronized(this) est suffisant.

+6

"autant de threads peuvent entrer dans le bloc qu'il y a instance" implique que la seconde forme agit comme un sémaphore qui n'est pas vrai. Vous devriez dire quelque chose comme: "synchronized (this) garantit qu'un seul thread peut entrer dans le bloc pour une instance donnée de la classe". – liwp

+0

Corrigé. J'avais l'intention de le dire. –

+1

Quelle est l'instance de classe par rapport à l'instance? –

18

Non, le premier sera obtenir un verrou sur la définition de la classe de MyClass, tous les cas de celui-ci. Cependant, si elle est utilisée dans une instance, elle bloquera toutes les autres instances puisqu'elles partagent une même définition de classe.

La seconde obtiendra un verrou sur l'instance actuelle uniquement. Pour savoir si cela rend vos objets threads sûrs, c'est une question beaucoup plus complexe - nous aurions besoin de voir votre code!

+1

Oui, MyClass.class peut être n'importe quelle variable statique et avoir le même effet. – pstanton

64

Pour ajouter aux autres réponses:

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

est équivalent à

static synchronized void myMethod() { 
    //code 
} 

et

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

est équivalent à

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

Il m'a fallu une deuxième lecture pour constater que les deux premiers exemples ont le mot-clé "statique". Juste en faisant remarquer cela à d'autres qui ont vu cela et l'ont manqué. Sans le mot-clé static, les deux premiers exemples ne seraient pas identiques. – kurtzbot