Beispielanalyse des Sichtbarkeitsproblems von Java-Variablen
Frage: Können Synchronisierung und Schlaf auch den Zweck der Sichtbarkeit flüchtiger Threads erreichen? Die allgemeine Problembeschreibung lautet wie folgt:
Paket com.test;
importiere java.util.concurrent.TimeUnit;
öffentlicher Klassentest1 {
privater statischer boolescher Wert ist = true;
public static void main(String[] args) {
neuer Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while(test1.is){
i++;
1 //synchronized (this) { } aktualisiert den Variablenwert des Hauptspeichers zwangsweise im Thread-Stapel?
2 //System.out.println("1"); println ist synchronisiert und erzwingt die Aktualisierung des Variablenwerts des Hauptspeichers im Thread-Stack?
3 //sleep lädt den Wert des Hauptspeichers neu?
// versuche es mit {
// TimeUnit.MICROSECONDS.sleep(1);
// }catch (InterruptedException e) {
// e.printStackTrace();
// }
}
}
}).start();
versuche es mit {
TimeUnit.SECONDS.sleep(1);
} Catch (InterruptedException e) {
e.printStackTrace();
}
neuer Thread(new Runnable() {
@Override
public void run() {
is = false; //Setze ist auf false, damit der obige Thread die while-Schleife beendet
}
}).start();
}
}
F: Warum wird nicht das gesamte Programm beendet? Warum wird das Programm beendet, wenn Sie einen der Codeblöcke (1, 2, 3) auskommentieren? Wird die Synchronisierung die Speichervariablenwerte zwangsweise im Thread-Stapel aktualisieren?
Beinhaltet Wissenserklärung
volatile: Dieses Schlüsselwort stellt die Sichtbarkeit von Variablen in Threads sicher, die vor dem Betrieb auf Variablen zugreifen, die durch volatile geändert wurden, und unmittelbar nach der Änderung des Arbeitsspeichers in den Hauptspeicher zurückschreiben, um sicherzustellen, dass andere Threads sichtbar sind Schlüsselwort mit derselben Wirkung ist endgültig.
synchronisiert: Alle Synchronisierungsvorgänge müssen 1. Atomizität und 2. Sichtbarkeit gewährleisten, sodass Änderungen, die im synchronisierten Block auftreten, sofort in den Hauptspeicher zurückgeschrieben werden
Schlaf: Diese Methode gibt nur CPU-Ausführungszeit auf und hebt die Sperre nicht auf.
Problemanalyse
F1: Warum wird das Programm nach dem Kommentieren des Codes nicht beendet?
A1: Da der Variablenwert „boolean is=true“ vom vorherigen Thread (als Thread A bezeichnet) in seinen eigenen Arbeitsspeicher geladen wird, ist dies möglicherweise nicht der Fall, nachdem der nachfolgende Thread (als Thread B bezeichnet) den booleschen Wert „is=false“ geändert hat sofort in den Hauptspeicher geschrieben werden (aber in dieser Frage sollte es sofort in den Hauptspeicher geschrieben werden, da der Thread nach der Ausführung von is=false beendet wird. Auch wenn er sofort in den Hauptspeicher geschrieben wird, kann es sein, dass Thread A dies nicht tut). sofort in den Arbeitsspeicher geladen werden, damit das Programm weiterläuft. Wird es nicht beendet? Daran denken die meisten von uns, aber tatsächlich wurde die JVM weitgehend für die aktuelle Hardwareebene optimiert und stellt im Wesentlichen die rechtzeitige Synchronisierung von Arbeitsspeicher und Hauptspeicher weitgehend sicher, was der Verwendung von Volatile entspricht standardmäßig. Aber nur im maximalen Umfang! Wenn die CPU-Ressourcen immer belegt sind, ist die Synchronisierung zwischen Arbeitsspeicher und Hauptspeicher, dh die Sichtbarkeit von Variablen, nicht so zeitnah! Die Schlussfolgerung wird später überprüft.
F2: Warum wird das Programm nur beendet, wenn ein Codeblock (1, 2, 3) unkommentiert ist?
A2: Die Codes mit den Zeilennummern 1 und 2 haben ein gemeinsames Merkmal, das heißt, sie beinhalten alle synchronisierte Synchronisationssperren. Daher werden, wie der Autor der Frage vermutet hat, die Variablenwerte im Hauptspeicher zwangsweise aktualisiert Thread-Stapel? Und die Schlafmethode aktualisiert auch die Variablenwerte im Hauptspeicher im Thread-Stapel? Tatsächlich haben wir zuvor gesagt, dass die Synchronisierung nur die Sichtbarkeit der Variablen im synchronisierten Block gewährleistet und sich die Variable is nicht im synchronisierten Block befindet, sodass dies offensichtlich nicht der Fall ist. Als nächstes fügen wir nach dem Code i++; den folgenden Code hinzu:
for(int k=0;k<100000;k++){
neues Objekt();
}
Führen Sie es erneut aus und das Programm wird sofort beendet! Warum? In A1 oben haben wir gesagt, dass selbst bei JVM-Optimierung die Sichtbarkeit der Daten nicht garantiert werden kann, genau wie das obige Programm ständig Schleifen ausführt, um i++-Operationen auszuführen. Und warum belegt das Programm die CPU? nach dem Hinzufügen des obigen Codes aufhören? Denn für eine große Anzahl neuer Object()-Operationen ist die CPU nicht mehr der zeitaufwändigste Vorgang. Der eigentliche Zeitaufwand sollte in der Speicherzuweisung liegen (da die Verarbeitungsgeschwindigkeit der CPU offensichtlich schneller ist als die des Speichers). , andernfalls gäbe es keine CPU-Register), sodass die CPU nach dem Leerlauf dem JVM-Optimierungsbenchmark folgt, um die Sichtbarkeit der Daten so schnell wie möglich sicherzustellen und dadurch die Variable is vom Hauptspeicher mit dem Arbeitsspeicher zu synchronisieren. Dies führt schließlich zum Ende des Programms. Aus diesem Grund beinhaltet die Methode „sleep()“ keine Synchronisierungsvorgänge, das Programm kann jedoch trotzdem beendet werden, da die Methode „sleep()“ die CPU freigibt, nicht jedoch die Sperre.
Das obige ist der detaillierte Inhalt vonBeispielanalyse des Sichtbarkeitsproblems von Java-Variablen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Leitfaden zum Zufallszahlengenerator in Java. Hier besprechen wir Funktionen in Java anhand von Beispielen und zwei verschiedene Generatoren anhand ihrer Beispiele.

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

Java ist eine beliebte Programmiersprache, die sowohl von Anfängern als auch von erfahrenen Entwicklern erlernt werden kann. Dieses Tutorial beginnt mit grundlegenden Konzepten und geht dann weiter zu fortgeschrittenen Themen. Nach der Installation des Java Development Kit können Sie das Programmieren üben, indem Sie ein einfaches „Hello, World!“-Programm erstellen. Nachdem Sie den Code verstanden haben, verwenden Sie die Eingabeaufforderung, um das Programm zu kompilieren und auszuführen. Auf der Konsole wird „Hello, World!“ ausgegeben. Mit dem Erlernen von Java beginnt Ihre Programmierreise, und wenn Sie Ihre Kenntnisse vertiefen, können Sie komplexere Anwendungen erstellen.
