Heim  >  Artikel  >  Java  >  Codeanalyse des flüchtigen Java-Schlüsselworts

Codeanalyse des flüchtigen Java-Schlüsselworts

不言
不言nach vorne
2018-10-22 14:43:322289Durchsuche

Der Inhalt dieses Artikels befasst sich mit der Codeanalyse des flüchtigen Java-Schlüsselworts. Ich hoffe, dass er für Freunde hilfreich ist.

Ich glaube, die meisten Java-Programmierer haben gelernt, wie man das Schlüsselwort volatile verwendet. Die Definition von volatile in der Baidu-Enzyklopädie:

Volatile ist ein Typspezifizierer, der dazu dient, Variablen zu ändern, auf die verschiedene Threads zugreifen und die sie ändern. volatile fungiert als Anweisungsschlüsselwort, um sicherzustellen, dass diese Anweisung aufgrund der Compileroptimierung nicht weggelassen wird und jedes Mal ein direktes Lesen des Werts erfordert.

Vielleicht gibt es viele Freunde, die gerade erst Java gelernt haben und nach dem Lesen der sehr allgemeinen Beschreibung oben immer noch verwirrt sind.

Lassen Sie uns anhand eines konkreten Beispiels lernen, wie man volatile verwendet.

Sehen Sie sich dieses Beispiel an:

public class ThreadVerify {
    public static Boolean stop = false;
    public static void main(String args[]) throws InterruptedException {
        Thread testThread = new Thread(){
            @Override
            public void run(){
                int i = 1;
                while(!stop){
                    //System.out.println("in thread: " + Thread.currentThread() + " i: " + i);
                    i++;
                }
                System.out.println("Thread stop i="+ i);
            }
        }
        ;
        testThread.start();
        Thread.sleep(1000);
        stop = true;
        System.out.println("now, in main thread stop is: " + stop);
        testThread.join();
    }
}

Dieser Code definiert einen booleschen Variablenstopp in der zweiten Zeile des Hauptthreads, und dann startet der Hauptthread einen neuen Thread und erhöht den Zähler im Der Wert von i beendet die Schleife erst, wenn die boolesche Variable stop des Hauptthreads vom Hauptthread auf true gesetzt wird.

Der Hauptthread pausiert für 1 Sekunde mit Thread.sleep und setzt den booleschen Wert stop auf true.

Codeanalyse des flüchtigen Java-Schlüsselworts

Daher erwarten wir, dass der obige Java-Code nach 1 Sekunde Ausführung stoppt und den tatsächlichen Wert des Zählers i ausgibt 1-Sekunden-Wert.

Nach der Ausführung dieser Java-Anwendung stellen Sie jedoch fest, dass sie in eine Endlosschleife gerät. Im Task-Manager stellen Sie fest, dass die CPU-Auslastung dieses Java-Programms stark ansteigt.

Was ist der Grund? Lassen Sie uns die im Computer-Hauptkurs „Betriebssysteme“ vermittelten Kenntnisse über Speichermodelle noch einmal Revue passieren lassen.

Nehmen Sie als Beispiel das Java-Speichermodell. Das Java-Speichermodell ist in Hauptspeicher und Arbeitsspeicher unterteilt. Die Variablen im Hauptspeicher werden von allen Threads gemeinsam genutzt. Jeder Thread verfügt über einen eigenen Arbeitsspeicher, und die darin enthaltenen Variablen umfassen Thread-lokale Variablen. Wenn eine Variable im Hauptspeicher von einem Thread verwendet wird, behält der Arbeitsspeicher des Threads eine Kopie der Hauptspeichervariablen bei.

Codeanalyse des flüchtigen Java-Schlüsselworts

Alle Lese- und Schreibvorgänge von Variablen durch Threads müssen im Arbeitsspeicher ausgeführt werden, und Variablen im Hauptspeicher können nicht direkt manipuliert werden. Verschiedene Threads können nicht direkt auf den Arbeitsspeicher des anderen zugreifen. Die Übertragung von Variablen zwischen Threads muss über den Hauptspeicher erfolgen. Die interaktive Beziehung zwischen Threads, Hauptspeicher und Arbeitsspeicher ist wie folgt:

Codeanalyse des flüchtigen Java-Schlüsselworts

Wenn der Thread die Definition in seinem eigenen Ausführungscode ändert, Variablen im Hauptthread (Hauptspeicher) werden direkt im Arbeitsspeicher des Threads geändert und dann zu einem bestimmten Zeitpunkt (der Java-Programmierer kann diesen Zeitpunkt nicht steuern, sondern wird von der JVM geplant) diese Änderung aus dem Arbeitsspeicher zurückgeschrieben. Arbeitsspeicher.

Zurück zu unserem Beispiel. Obwohl der Hauptthread die Stoppvariable ändert, ändert er nur den Wert im Hauptspeicher, während die Stoppvariable im Arbeitsspeicher des Threads, der den Zähler betreibt, immer noch den alten Wert hat, der immer falsch ist. Deshalb steckt dieser Thread in einer Endlosschleife fest.

Codeanalyse des flüchtigen Java-Schlüsselworts

Sobald Sie das Prinzip kennen, ist die Lösung einfach. Fügen Sie das Schlüsselwort volatile vor der Stoppvariablen hinzu, um es zu ändern, sodass Volatile den Thread jedes Mal, wenn der Stoppwert im Zählerthread gelesen wird, dazu zwingt, aus dem Hauptspeicher zu lesen, anstatt aus dem Arbeitsspeicher des aktuellen Threads zu lesen. Dadurch wird eine Endlosschleife vermieden. Das Bild unten zeigt, dass der Zähler nach 1 Sekunde 1,4 Milliarden Mal ausgeführt wurde.

Codeanalyse des flüchtigen Java-Schlüsselworts

Das obige ist der detaillierte Inhalt vonCodeanalyse des flüchtigen Java-Schlüsselworts. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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