Lies http://www.ibm.com/developerworks/java/library/j-dcl.html und erkläre, wo es genau bei
public static Singleton getInstance() { if (instance == null) { synchronized(Singleton.class) { //1 if (instance == null) //2 instance = new Singleton(); //3 } } return instance; }
zu einem Problem bei nebenläufigen Threads kommen kann. Warum funktioniert es auch bei 2 synch. Blöcken nicht? Was hat das dem Memory-Modell zu tun?
Hinweis: Es geht nicht darum, ein Singleton korrekt zu implementieren, sondern das Java Memory Modell zu verstehen und Probleme aufzudecken, die sich aus der Nebenläufigkeit ergeben.
Seit Java 5 ist das »Double-checked locking« einfach nicht mehr die beste Möglichkeit, ein sicheres Singelton zu realisieren – am sichersten (und mit dem geringsten Schreibaufwand) ist der Weg über ein Enum. Diese Idee sieht auf den ersten Blick zwar etwas merkwürdig (bzw. zweckentfremdet) aus, ist aber auch lt. »Effectice Java« die beste Möglichkeit.
Hallöchen,
unter Java 5 kann man das Double-checked locking sicher implementieren, wenn die Instanzvariable volatile deklariert wird.
Da es sich beim Singleton um eine statische Variable handelt könnte neben dem schon angesprochenen Weg über das Enum, auch das sog. „Lazy initialization holder class idiom“ implementiert werden (vgl. http://java.sun.com/developer/technicalArticles/Interviews/bloch_effective_08_qa.html).
Ein sehr schönes Interview, vielen Dank für den Link!