Solo Java 5 e versioni successive. Assumi un computer con memoria condivisa multiprocessore (probabilmente ne stai usando uno proprio ora).Java keyword sincronizzata svuota la cache?
Ecco un codice per la pigra inizializzazione di un Singleton:
public final class MySingleton {
private static MySingleton instance = null;
private MySingleton() { }
public static MySingleton getInstance() {
if (instance == null) {
synchronized (MySingleton.class) {
if (instance == null) {
instance = new MySingleton();
}
}
}
return instance;
}
}
Fa instance
devono essere dichiarati volatile
al fine di evitare che l'ottimizzatore di riscrittura getInstance() come segue (che sarebbe corretto in un sequenziale programma):
public static MySingleton getInstance() {
if (instance == null) {
synchronized (MySingleton.class) {
// instance must be null or we wouldn't be here (WRONG!)
instance = new MySingleton();
}
}
}
Supponendo che l'ottimizzatore non riscrivere il codice, se instance
non è dichiarato volatile
è ancora garantito per essere lavata alla memoria quando il blocco synchronized
viene chiuso e letto dalla memoria quando viene inserito il blocco synchronized
?
EDIT: Ho dimenticato di rendere getInstance() statico. Non penso che cambi la validità delle risposte; sapevi tutti cosa intendevo.
Suggerimento: è possibile utilizzare 'javap -c com.example.ClassName' per disassemblare il codice in modo da poter verificare come è stato compilato e se il compilatore ha modificato/ottimizzato l'uno o l'altro. Ho controllato per te con quello di JDK 1.6 e il compilatore non ha rimosso il nidificato 'if'. – BalusC
L'uso di javap è interessante, ma l'ottimizzatore di javac è in genere piuttosto scarso. Di proposito. Il vero ottimizzatore è nel compilatore JIT in fase di esecuzione. – Darron
Mi scuso per aver controllato solo una delle risposte come "La risposta". Tutti loro meritano finora di essere controllati, ma mi permettono solo di controllarne uno. –