2010-01-13 14 views
68

Cosa significa questo codice java? Otterrà il blocco su tutti gli oggetti di MyClass?Blocco sincronizzato Java per .class

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

E come il codice di cui sopra è diversa da questa:

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

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

risposta

111

Lo snippet synchronized(X.class) utilizza l'istanza di classe come monitor. Poiché esiste una sola istanza di classe (l'oggetto che rappresenta i metadati della classe in fase di esecuzione), un thread può trovarsi in questo blocco.

Con synchronized(this) il blocco è protetto dall'istanza. Per ogni istanza, solo un thread può entrare nel blocco.

synchronized(X.class) viene utilizzato per assicurarsi che esista esattamente una filettatura nel blocco. synchronized(this) assicura che esista esattamente un thread per istanza. Se questo rende il codice effettivo nel blocco thread-safe dipende dall'implementazione. Se lo stato di solo mutata dell'istanza è synchronized(this) è sufficiente.

+6

"quanti thread possono entrare nel blocco in quanto esistono istanze" implica che il secondo modulo agisca come un semaforo che non è vero. Dovresti dire qualcosa del tipo: "sincronizzato (questo) garantisce che solo un thread possa entrare nel blocco per una data istanza della classe". – liwp

+0

corretto. Intendevo dirlo. –

+1

qual è l'istanza di classe rispetto all'istanza? –

18

No, il primo otterrà un blocco sulla definizione della classe di MyClass, non tutte le istanze di esso. Tuttavia, se utilizzato in un'istanza, bloccherà efficacemente tutte le altre istanze, poiché condividono una singola definizione di classe.

Il secondo otterrà un blocco solo sull'istanza corrente.

Se questo rende i thread degli oggetti sicuri, questa è una domanda molto più complessa - dovremmo vedere il tuo codice!

+1

sì, MyClass.class potrebbe essere una qualsiasi variabile statica e avere lo stesso effetto. – pstanton

64

da aggiungere alle altre risposte:

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

è equivalente a

static synchronized void myMethod() { 
    //code 
} 

e

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

equivale a

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

Mi ci è voluta una seconda lettura per capire che i primi due esempi hanno la parola chiave "statico". Basta indicarlo agli altri che potrebbero averlo visto e averlo perso. Senza la parola chiave statica, i primi due esempi non sarebbero gli stessi. – kurtzbot

Problemi correlati