Heim  >  Artikel  >  Java  >  Was ist der Java-Double-Check-Lock-Modus?

Was ist der Java-Double-Check-Lock-Modus?

WBOY
WBOYnach vorne
2023-05-19 15:29:491461Durchsuche

Ursache

Ich bin auf ein solches Problem gestoßen, als ich die statische PMD-Codeerkennung für das Projekt durchführte.

Teilweise erstellte Objekte können durch das Double Checked Locking-Muster zurückgegeben werden, wenn es in Java verwendet wird. Eine optimierende JRE kann der Baz-Variablen einen Verweis zuweisen bevor es den Konstruktor des Objekts aufruft, auf das die Referenz verweist.

Hinweis: Mit Java 5 können Sie dafür sorgen, dass die doppelt geprüfte Sperre funktioniert, wenn Sie die Variable als flüchtig deklarieren.

möglicherweise, wenn Sie den doppelt geprüften Sperrmodus verwenden Gibt ein unvollständig initialisiertes Objekt zurück. Einige Leute bezweifeln möglicherweise das Konzept teilweise initialisierter Objekte. Bitte analysieren Sie weiter.

Was ist der Doppelprüfungs-Sperrmodus? Threads können die if-Beurteilung außerhalb des synchronisierten Codeblocks gleichzeitig eingeben. Wenn innerhalb des synchronisierten Codeblocks keine Nullbeurteilung durchgeführt wird, können mehrere Instanzen initialisiert werden.

Das Problem

Diese Schreibweise scheint perfekt zu sein, ist aber problematisch oder garantiert nicht, dass sie perfekt sein wird. Der Hauptgrund ist, dass es sich bei der Instanz = new Singleton(); nicht um eine atomare Operation handelt.

Das Erstellen eines Objekts kann in drei Teile unterteilt werden:

<code>public static Singleton getSingleton() {<br>    if (instance == null) {                        <br>        synchronized (Singleton.class) {<br>            if (instance == null) {                 <br>                instance = new Singleton();<br>            }<br>        }<br>    }<br>    return instance ;<br>}</code> 

Allerdings kann es zwischen den Schritten 2 und 3 neu angeordnet werden, wodurch die Reihenfolge der Objekterstellung 1-3-2 wird: Thread A für Erstellen Sie zum ersten Mal das Objekt Singleton und die Reihenfolge der Objekterstellung ist 1-3-2.

Nachdem der Instanz Speicher zugewiesen wurde, kommt ein Thread B und ruft die Methode getSingleton() auf.
Zu diesem Zeitpunkt wird diese Instanz beurteilt == null, und es wird festgestellt, dass die Instanz nicht Nicht null ist.
Beachten Sie jedoch, dass die Instanz das Objekt zu diesem Zeitpunkt noch nicht initialisiert hat und Thread B das nicht initialisierte Objekt zurückgibt. Wenn Thread B die Instanz verwendet, können Probleme auftreten. Dies ist das Problem der Doppelprüfungssperre.

Verwenden Sie flüchtig

Für die oben genannten Probleme können wir das obige Problem lösen, indem wir die Instanz als flüchtig deklarieren

<code>1.分配对象的内存空间<br>2.初始化对象<br>3.设置instance指向刚分配的内存地址<br>当instance指向分配地址时,instance是不为null的</code> 

Aber sie muss in der JDK5-Version oder höher verwendet werden.

Statische innere Klasse

<code>public class Singleton{<br>    private volatile static Singleton instance;<br>    public static Singleton getSingleton() {<br>        if (instance == null) {                        <br>            synchronized (Singleton.class) {<br>                if (instance == null) {                 <br>                    instance = new Singleton();<br>                }<br>            }<br>        }<br>        return instance ;<br>    }<br>}</code> 

Die derzeit empfohlene Schreibweise ist die Verwendung statischer innerer Klassen, die ein verzögertes Laden ohne Thread-Sicherheitsprobleme erreichen können. Und es reduziert den Overhead der Synchronisierung.

Das obige ist der detaillierte Inhalt vonWas ist der Java-Double-Check-Lock-Modus?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen