English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

学习Java内存模型JMM心得

Manchmal führen Optimierungen durch Compiler und Prozessor dazu, dass das Laufzeitresultat anders ist, als erwartet. Daher hat Java einige Einschränkungen für Compiler und Prozessor festgelegt, Java Memory Model (JMM) abstract diese, so dass beim Schreiben von Code nicht viele unterirdische Details berücksichtigt werden müssen und gewährleistet wird, "Wenn die Regeln des JMM beim Schreiben von Programmen befolgt werden, ist das Laufzeitresultat immer korrekt."

JMM-Abstraktionsstruktur

In Java werden alle Instanzen und statischen Variablen im Heapmemory gespeichert, das Heapmemory kann zwischen Threads gemeinsam genutzt werden, dies wird auchGemeinsam genutzte Variable. Lokale Variablen, Methodenparameter und Ausnahmebehandlungparameter sind im Stack, und Stackmemory wird nicht zwischen Threads gemeinsam genutzt.

Daher können Optimierungen durch Compiler und Prozessor zu Sichtbarkeitsproblemen bei gemeinsam genutzten Variablen führen, wie in Multicore-Prozessoren (multi-Prozessor), ein Thread kann auf verschiedenen Prozessoren ausgeführt werden, undInkonsistenz zwischen Prozessoren kann zu Sichtbarkeitsproblemen bei gemeinsam genutzten Variablen führen, ist es möglich, dass zwei Threads denselben Variable unterschiedliche Werte sehen.

JMM (Java Memory Model)抽象isiert diese Optimierungen der Hardware in jedem Thread, der eine lokale Memory hat. Wenn es erforderlich ist, gemeinsam genutzte Variablen zu lesen und zu schreiben, wird eine Kopie aus dem Hauptmemory in die lokale Memory kopiert. Wenn gemeinsam genutzte Variablen geschrieben werden, werden sie zunächst in die lokale Memory geschrieben und zu einem späteren Zeitpunkt in den Hauptmemory zurückgespielt. Wenn gemeinsam genutzte Variablen erneut gelesen werden, wird nur aus der lokalen Memory gelesen.

So dass die Kommunikation zwischen Threads in zwei Schritten erfolgen muss:

Schreib-Thread: Aktualisiere den lokalen Speicher in den Hauptmemory. Lesethread: Lese den aktualisierten Wert aus dem Hauptmemory

So in Schreiben-Es gibt eine Verzögerung zwischen dem Lesen: Wann wird das lokale Speicher in den Hauptmemory zurückgespielt? Dies führt zu Sichtbarkeitsproblemen, und verschiedene Threads können verschiedene gemeinsam genutzte Variablen sehen.

passiert-vor

In der Regel passiert-before bedeutet "passiert vor dieser Zeit". Dies sind die Regeln, die Java für die Reihenfolge der Programmausführung festgelegt hat, und die Implementierung der Synchronisation muss dieser Regel folgen. Auf diese Weise muss der Programmierer nur ein korrektes Synchronisationsprogramm schreiben, passiert-before garantiert, dass das Laufzeitresultat nicht falsch ist.

A tritt ein-before B bedeutet nicht nur, dass A vor B ausgeführt wird, sondern auch, dass das Ausführungsresultat von A für B sichtbar ist, was die Sichtbarkeit garantiert.

A tritt ein-before B, bedeutet nicht unbedingt, dass A vor B ausgeführt wird. Wenn A und B abwechselnd ausgeführt werden, ist das Ausführungsresultat immer noch korrekt, dann ist es erlaubt, Compiler und Prozessor zu optimieren und umzuordnen. Daher ist es egal, wie Compiler und Prozessor optimieren und umordnen, solange das Programmresultat korrekt ist, das ist in Ordnung.

passiert-before-Regel

Programm-Reihenfolgeregeln: Vorherige Operationen passiert in einem Thread-before-Operationen-Sperrenregeln: Entsperren passiert für denselben Sperren-before-Sperre volatile-Domäneregeln: Schreiben eines volatile- Variablen, passiert-Transitivität für jede Lesung dieser volatile Variable nach vorne: A tritt ein-vor B, dann tritt B ein-vor C, dann tritt A ein-vor ThreadB.start() Regel: Wenn ThreadA ThreadB.start() ausführt, dann tritt ThreadB.start() ein-vor jede Operation von ThreadB join() Regel: Wenn ThreadA ThreadB.join() ausführt, dann treten alle Operationen in ThreadB ein-vor ThreadB.join()

Dieser Beispiel hilft zu verstehen, was passiert-vor

double pi = 3.14; //A
double r = 1.0; //B
double area = pi * r *r; //C

Hier gibt es drei tritt ein-Beziehung vor, Regel1,2ist die Regel der Programmsortierreihenfolge, Regel3wird durch das transitiven Regel der Regel abgeleitet:

A tritt ein-vor B, B tritt ein-vor C, A tritt ein-vor C

C hängt von A und B ab, aber weder A noch B hängt von jemandem ab. Daher ändert sich das Ausführungsresultat nicht, wenn A und B umsortiert werden, diese Umsortierung wird vom JMM durchgeführt.

Die Ergebnisse der beiden folgenden Ausführungsreihenfolgen sind beide korrekt.

Dies ist der gesamte Inhalt unserer Zusammenfassung der Lernmeinungen über das Java-Memory-Model (JMM), weitere Fragen können Sie unten kommentieren und diskutieren. Vielen Dank für Ihre Unterstützung des呐喊教程.

Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet entnommen und gehört dem Urheberrecht des jeweiligen Autors. Der Inhalt wurde von Internetnutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht von Hand bearbeitet. Sie übernimmt keine Haftung für rechtliche Konsequenzen. Wenn Sie Inhalte mit fraglichem Urheberrecht finden, freuen wir uns über eine E-Mail an: notice#oldtoolbag.com (Bitte ersetzen Sie # durch @ beim Senden einer E-Mail zur Meldung von Missbrauch und stellen Sie relevante Beweise zur Verfügung. Bei nachgewiesener Infringement wird die Website die betreffenden Inhalte sofort löschen.)