In JLS, § 17.4. 5. Geschieht-vor der Bestellung , es sagt das
Ein Programm wird genau dann synchronisiert, wenn alle sequentiell konsistenten Ausführungen frei von Datenrennen sind.
Laut Diskussion in < em> Lässt ein richtig synchronisiertes Programm noch Datenrennen zu (Teil I) , erhalten wir folgende Schlussfolgerung:
Ein Programm kann korrekt synchronisiert werden und Datenrennen haben.
Die Kombination von zwei Schlussfolgerungen bedeutet, dass es ein solches Beispiel geben muss:
Alle sequentiell konsistenten Ausführungen eines Programms sind datenlauffrei, aber die normalen Ausführungen (Ausführungen, die nicht sequentiell konsistente Ausführungen sind) eines solchen Programms enthalten Datenrennen.
Nach langem Überlegen kann ich immer noch kein solches Codebeispiel finden. Also was ist mit dir?
Es ist nicht wahr, dass "ein Programm korrekt synchronisiert werden kann und Datenrennen haben". Das Beispiel von assylias in dieser Diskussion ist nicht korrekt synchronisiert . Es ist korrekt vom übergeordneten funktionalen Standpunkt aus - das Datenrennen, das es enthält, zeigt sich nicht als Fehler. Es ist ein sogenanntes "gutartiges" Datenrennen, aber das ist irrelevant, wenn man die JLS-Definitionen diskutiert.
Ein Programm, dessen sequentiell konsistente Ausführung keine Datenrennen enthält, garantiert garantiert keine Datenrennen in irgendeiner Ausführung, sequentiell konsistent oder nicht. Wie die JLS sagt,
Dies ist eine extrem starke Garantie für Programmierer. Programmierer müssen nicht über Neuanordnungen nachdenken, um festzustellen, dass ihr Code Datenrennen enthält. Daher müssen sie bei der Bestimmung, ob ihr Code korrekt synchronisiert ist, nicht über Neuordnungen nachdenken. Sobald die Feststellung getroffen ist, dass der Code korrekt synchronisiert ist, muss sich der Programmierer nicht sorgen, dass Umordnungen seinen Code beeinflussen.
Bitte beachten Sie, dass die Definition eines korrekt synchronisierten Programms nur auf sequentiell konsistente Ausführungen beschränkt ist [em] als eine Höflichkeit gegenüber dem Programmierer , was ihm die starke Garantie gibt, dass sequentiell konsistente Ausführungen die einzigen sind oder sie muss darüber nachdenken und alle anderen Ausführungen haben automatisch die gleiche Garantie.
Es ist leicht, sich in der Terminologie des JMM zu verlieren und subtile Fehlinterpretationen führen später zu tiefen Missverständnissen. Nimm dir deshalb diese zu Herzen:
Dies ist eine kontraintuitive Definition, daher müssen wir vorsichtig sein: Jedes Mal, wenn wir Ausführung sagen, müssen wir uns eine
Es ist interessant festzustellen, dass die Synchronisationsreihenfolge zu einer Gesamtbestellung würde, wenn all Ihre geteilten vars flüchtig wären und als solche die Definition der Ausführungsreihenfolge . Auf diese Weise kommen wir aus einem anderen Blickwinkel zu der Schlussfolgerung, dass alle Ausführungen eines solchen Programms sequentiell konsistent wären.
Ich habe tief gegraben, um den JLS-Fehler in der Definition eines Datenrennens zu verstehen:
"Wenn ein Programm zwei in Konflikt stehende Zugriffe (§ 17.4.1) enthält, die nicht durch eine happes-before Beziehung angeordnet sind, wird gesagt, dass es ein Datenrennen enthält."
Zunächst ist es nicht das Programm , das Datenrennen enthält, sondern eine Programmausführung . Wenn wir uns wieder auf das Originalpapier beziehen, das das Java-Speichermodell definiert, sehen wir, dass dies korrigiert wird:
"Zwei Zugriffe x und y bilden bei der Ausführung eines Programms eine Datenrasse, wenn sie aus verschiedenen Threads stammen, sie konfligieren und nicht nach
Dies führt jedoch immer noch dazu, dass volatile Variablen als Datenrennen definiert werden. Betrachten Sie das folgende Diagramm hases-before :
%Vor%r1 Beobachter der Schreib w1 .Es wurde von einem anderen zu lesen, r0 , und die Schreib voraus durch eine andere gefolgt, w2 . Beachten Sie jetzt gibt es keinen Weg zwischen r0 und entweder w1 oder w2 ; ebenfalls zwischen r1 und w2 . All dies sind Beispiele eines Daten Rennen durch die Definition.
noch tiefer Graben, aber ich habe festgestellt, diesen Beitrag auf der memoryModel Mailingliste . Es sagt "eine Daten Rennen sollte als widersprüchliche Aktionen auf nicht-flüchtigen Variablen definiert werden die nicht von hours-before angeordnet werden. "Nur mit dieser Hinzufügung würde die Lücke geschlossen, aber diese hat noch nicht die offizielle JLS-Version betreten.
Tags und Links java memory-model jls