Warum schreibgeschützte und flüchtige Modifikatoren sich gegenseitig ausschließen?

8

Ich habe eine Referenzvariable, die readonly ist, weil sich die Referenz nie ändert, nur ihre Eigenschaften. Als ich versuchte, den Modifizierer volatile hinzuzufügen, warnte mich der Kompilierte, dass beide Modifikatoren nicht auf die gleiche Variable angewendet werden könnten. Aber ich denke, ich brauche es, um flüchtig zu sein, weil ich keine Cache-Probleme haben will, wenn ich seine Eigenschaften lese. Fehle ich etwas? Oder ist der Compiler falsch?

Aktualisieren Wie Martin in einem der folgenden Kommentare ausgeführt hat: Sowohl readonly als auch volatile Modifikatoren gelten nur für die Referenz und nicht für die Eigenschaften des Objekts im Falle von Objekten vom Referenztyp. Das habe ich vermisst, also hat der Compiler Recht.

%Vor%     
Jader Dias 28.12.2008, 16:55
quelle

3 Antworten

14

Weder die Modifizierer readonly noch volatile sind penetrativ. Sie gelten für die Referenz selbst, nicht für die Eigenschaften des Objekts.

Das Schlüsselwort readonly bestätigt, dass eine -Variable sich nach der Initialisierung nicht ändern kann. Die Variable ist der kleine Teil des Speichers, in dem die Referenz gespeichert ist.

Das Schlüsselwort volatile teilt dem Compiler mit, dass der Inhalt einer Variablen möglicherweise von mehreren Threads geändert wird. Dadurch wird verhindert, dass der Compiler Optimierungen (z. B. das Lesen des Werts der Variablen in ein Register und die Verwendung dieses Werts über mehrere Anweisungen) verwendet, die Probleme beim gleichzeitigen Zugriff verursachen könnten. Dies betrifft wiederum nur den kleinen Speicherbereich, in dem die Referenz gespeichert ist.

Auf diese Weise können Sie sehen, dass sie sich gegenseitig ausschließen. Wenn etwas nur gelesen wird (kann nur einmal geschrieben werden, bei der Initialisierung oder Konstruktion), dann kann es auch nicht flüchtig sein (kann jederzeit von mehreren Threads beschrieben werden).

Was Ihr Bedenken bezüglich der Caching-Probleme, IIRC, angeht, gibt es ziemlich strenge Regeln darüber, wann der Compiler das Ergebnis eines Property-Aufrufs zwischenspeichern kann. Denken Sie daran, dass ein Methodenaufruf ist, und es ist eine ziemlich schwere Optimierung (vom Standpunkt des Compilers aus), seinen Wert zwischenzuspeichern und den Aufruf des Aufrufs zu überspringen. Ich denke nicht, dass es etwas ist, worüber du dich zu sehr kümmern musst.

    
P Daddy 28.12.2008, 17:22
quelle
1

Ein schreibgeschütztes Feld kann nur geschrieben werden, wenn das Objekt zuerst konstruiert wird. Daher wird es kein Caching-Problem auf der CPU geben, da das Feld unveränderlich ist und sich nicht ändern kann.

    
nbevans 28.12.2008 17:02
quelle
0

Obwohl die Referenz selbst Thread-sicher sein kann, sind ihre Eigenschaften möglicherweise nicht. Denken Sie darüber nach, was passieren würde, wenn zwei Threads gleichzeitig versuchen würden, eine List innerhalb Ihres Referenzobjekts zu durchlaufen.

    
Charlie Salts 28.12.2008 17:08
quelle