Penguncian Ganda. Umumnya.
Paradigma, yang saya mulai pelajari dari masalah ketika saya bekerja di BEA, adalah bahwa orang akan memeriksa singleton dengan cara berikut:
public Class MySingleton {
private static MySingleton s_instance;
public static MySingleton getInstance() {
if(s_instance == null) {
synchronized(MySingleton.class) { s_instance = new MySingleton(); }
}
return s_instance;
}
}
Ini tidak pernah berhasil, karena utas lain mungkin telah masuk ke blok yang disinkronkan dan s_instance tidak lagi nol. Jadi perubahan alami adalah membuatnya:
public static MySingleton getInstance() {
if(s_instance == null) {
synchronized(MySingleton.class) {
if(s_instance == null) s_instance = new MySingleton();
}
}
return s_instance;
}
Itu juga tidak berhasil, karena Java Memory Model tidak mendukungnya. Anda perlu mendeklarasikan s_instance sebagai volatile untuk membuatnya berfungsi, dan itupun hanya berfungsi di Java 5.
Orang yang tidak terbiasa dengan seluk-beluk Model Memori Java mengacaukan ini sepanjang waktu .