Scala val muss für den gleichzeitigen Zugriff synchronisiert werden?

7

Wie ich gelesen habe, wird Scala immutable val aus verschiedenen Gründen nicht in Java final übersetzt. Bedeutet dies, dass der Zugriff auf val von einem anderen Thread mit Synchronisation geschützt werden muss, um Sichtbarkeit zu gewährleisten?

    
ron 16.03.2011, 14:59
quelle

2 Antworten

9

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:

%Vor%

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 ...

deklariert wurde     
axel22 16.03.2011, 15:13
quelle
12

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%     
Paolo Falabella 16.03.2011 15:14
quelle

Tags und Links