Wie wir wissen, hat einfache Doppelprüfung Problem wegen der Befehl Umsortieren von der JVM.Java Singleton mit Double Check
Wenn ich die Instance = new MyClass();
zu den kommentierten Zeilen ersetzen. Funktioniert das?
Wie wir wissen, hat einfache Doppelprüfung Problem wegen der Befehl Umsortieren von der JVM.Java Singleton mit Double Check
Wenn ich die Instance = new MyClass();
zu den kommentierten Zeilen ersetzen. Funktioniert das?
Nein, das funktioniert nicht. Betrachte Thread A und B; Thread A sieht, dass Instance
null
ist und trägt den synchronisierten Block ein, um eine Instanz von MyClass
zu erstellen und dem Feld Instance
zuzuweisen.
Aufgrund der Regeln des Java Memory Model kann eine Neuordnung auftreten und ein teilweise initialisiertes oder sogar nicht initialisiertes Objekt von MyClass
kann Instance
zugewiesen werden. Jetzt geht Thread B in dieselbe GetInstance
-Methode und sieht, dass Instance
nicht null ist, tritt niemals auf dem gleichen Monitor wie Thread A in einen synchronisierten Block ein und gibt dann ein Objekt zurück, das nicht vollständig initialisiert ist.
Ob Sie die Initialisierung in zwei Codezeilen aufteilen oder in einer Zeile belassen, ist für dieses Problem absolut bedeutungslos: In beiden Fällen kann eine Neuordnung erfolgen. Der Java-Compiler könnte legal beide Versionen Ihres Codes mit demselben Bytecode kompilieren (obwohl der aktuelle Compiler dies nicht tut)
Sie meinen, Compiler kann den Code optimieren, als Ergebnis wird kein Unterschied machen. Danke vielmals . –
Nein. Machen Sie es einfach ['volatile'] (https://en.wikipedia.org/wiki/ Double-checked_locking # Usage_in_Java). –
MyClass obj = neu MyClass(); wird eine neue Instanz zurückgeben und dann wird Instanz mit dem Objekt zugewiesen. Warum funktioniert das nicht? Ich weiß wirklich nicht warum. –
Es gibt fast keinen Grund, die Sperrung zu überprüfen, selbst bei einer korrekten Implementierung mit 'volatile'. Lazy-instanziierte Singletons sollten das [Initialization on demand holder idiom] (https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom) verwenden. – Radiodef