Als Objektmitglieder ändern val
s nach der Initialisierung niemals ihre Werte während der Lebensdauer des Objekts. Daher sind ihre Werte garantiert für alle Threads sichtbar, vorausgesetzt, dass der Verweis auf das Objekt im Konstruktor nicht aufgehoben wurde. Und tatsächlich erhalten sie Java final
-Modifikatoren wie unten dargestellt:
Verwenden von javap:
%Vor% Als Methoden-Locals werden sie nur innerhalb der Methode verwendet, oder sie werden als Argumente an eine geschachtelte Methode oder eine Closure übergeben (siehe oben " bar
" genannt). Eine Schließung kann an einen anderen Thread weitergegeben werden, aber es wird nur ein letztes Feld mit dem Wert der lokalen val
haben. Daher sind sie von dem Punkt, an dem sie erstellt wurden, für alle anderen Threads sichtbar, und eine Synchronisierung ist nicht erforderlich.
Beachten Sie, dass dies nichts über das Objekt sagt, auf das val
zeigt - es selbst kann veränderbar sein und eine Synchronisation gewährleisten.
In den meisten Fällen kann das Obige nicht durch Reflektion verletzt werden - die Scala val
-Member-Deklaration erzeugt tatsächlich einen Getter mit demselben Namen und ein privates Feld, auf das der Getter zugreift. Wenn Sie versuchen, die Reflektion zu verwenden, um das Feld zu ändern, wird NoSuchFieldException
angezeigt. Die einzige Möglichkeit, sie zu ändern, besteht darin, der Klasse eine specialized
Annotation hinzuzufügen, die die speziellen Felder schützt und damit für Reflektionen zugänglich ist. Ich kann mir momentan keine andere Situation vorstellen, die etwas ändern könnte, das als val
...
Die Zuweisung zu val selbst ist aus Sicht des Multi-Threading gut, weil Sie val einen Wert zuweisen müssen, wenn Sie ihn deklarieren, und dieser Wert kann in der Zukunft nicht geändert werden (wenn Sie also ein% co_de machen %, s ist "Hallo" von seiner Geburt an: kein Thread wird jemals einen anderen Wert lesen). Es gibt jedoch ein paar Vorbehalte:
1 - Wenn Sie eine Instanz einer veränderbaren Klasse val zuweisen, schützt val nicht selbst den internen Status der Klasse davor, sich zu ändern.
%Vor%2 - Sie (oder eine Ihrer Bibliotheken ...) können ein val durch Reflektion ändern. Wenn dies passiert, könnten zwei Threads tatsächlich einen anderen Wert für Ihr val
lesen %Vor%Tags und Links scala concurrency immutability