Kausalität in JMM scheint der verwirrendste Teil davon zu sein. Ich habe einige Fragen bezüglich der JMM-Kausalität und erlaubte Verhaltensweisen in gleichzeitigen Programmen.Warum ist dieses Verhalten im Java Memory Model erlaubt?
Wie ich verstehe, verbietet das aktuelle JMM immer Kausalitätsschleifen. (Habe ich recht?)
nun gemäß dem JSR-133 Dokument, Seite 24, Abb.16, haben wir ein Beispiel, wo:
Anfangs x = y = 0
Gewinde 1:
r3 = x;
if (r3 == 0)
x = 42;
r1 = x;
y = r1;
Thread 2:
r2 = y;
x = r2;
Intuitiv scheint r1 = r2 = r3 = 42
unmöglich. Es wird jedoch nicht nur als möglich erwähnt, sondern auch in JMM erlaubt.
Für die Möglichkeit, die Erklärung aus dem Dokument, das ich nicht verstehen ist,:
Ein Compiler bestimmen könnte, dass die einzigen Werte je zugewiesen
x
sind 0 und 42. Von dass der Compiler konnte ableiten, dass an dem Punkt, wo wirr1 = x
ausführen, entweder wir hatten gerade eine Schreib von 42 bisx
durchgeführt wird, oder wir hatten gerade gelesenx
und den Wert 42. In jedem Fall gesehen, es würde für eine Lese legal vonx
, um den Wertzu sehen42. Es könnte sich dann ändernr1 = x
zu ; dies würde ermöglichen,y = r1
iny = 42
umgewandelt und früher durchgeführt werden, was zu dem Verhalten in Frage. In diesem Fall wird der Schreibvorgang aufy
zuerst festgeschrieben.
Meine Frage ist, welche Art von Compiler-Optimierung ist es wirklich? (Ich bin Compiler-Ignorant.) Da 42 nur bedingt geschrieben wird, wenn die if
-Anweisung erfüllt ist, wie kann der Compiler entscheiden, mit dem Schreiben von x
zu gehen? Zweitens
, auch wenn Compiler erledigt diese spekulative Optimierung und begeht y = 42
und dann schließlich macht r3 = 42
, ist es nicht eine Verletzung der Kausalität Schleife, da es keine Ursache und Wirkung unterscheiden verlassen nun?
Tatsächlich gibt es ein Beispiel im selben Dokument (Seite 15, Abbildung 7), wo eine ähnliche Kausalschleife als inakzeptabel erwähnt wird.
Wie kommt es, dass diese Ausführungsreihenfolge in JMM zulässig ist?
@Alexei Das erklärt einiges davon. Aber sollte der Compiler nicht "r3 = 0" statt "r3 = 42" machen? Oder sie zeigen nur "eine Möglichkeit"! – gaganbm
Compiler macht 'r3 = 42' nicht, es lässt nur 'r3 = x' intakt. Die Compiler-Optimierung wird nicht immer bis zur maximalen Tiefe ausgeführt. Wenn die Wahrscheinlichkeit, dass die Optimierung die Korrektheit verletzt, minimal ist, wird sie aufgegeben. In dem angegebenen Code gibt es keine solchen Umstände, aber sie können auftreten, wenn ein anderer Code vorhanden ist. Außerdem kann der Compiler entscheiden, dass "r3 = 0" den gleichen Preis wie "r3 = x" hat. –