Sichtbarkeit der Zuweisung zur Variablen in Java

8

Ich habe kürzlich mit einem Freund über einen Code wie diesen gestritten:

%Vor%

Ich habe argumentiert, dass es möglich ist, dass value als 0 in Y angesehen werden kann, da es keine Garantie dafür gibt, dass die Zuweisung value = initializeValue() in den Threads des Executors sichtbar ist. Ich sagte, er müsste value zu einem volatilen Feld machen.

Er widersprach mir und sagte, da es ein privates Instanzfeld mit dem Wert ist, der vor der Erstellung des Threads zugewiesen wurde, ist der Wert sichtbar.

Ich schaute in Ссылка , aber ich konnte nicht Ich denke nicht, was genau ich als Hintergrund für meine Aussage verwenden kann. Kann mir jemand helfen? Danke!

    
Marc G 28.02.2016, 13:20
quelle

2 Antworten

10

Es ist irrelevant, ob es privat ist oder nicht. Was relevant ist, ist dies:

  

Speicherkonsistenzeffekte: Aktionen in einem Thread vor dem Senden eines   Runnable-Objekt zu einem Executor, bevor die Ausführung beginnt   vielleicht in einem anderen Thread.

Von Executor-Dokumenten . Das bedeutet, dass alles, was Sie vor dem Aufruf von submit tun, im Runnable sichtbar ist. Sie können es sogar nach dem Konstruieren des Executors tun, und in diesem speziellen Fall spielt es keine Rolle, wann der ausführende Thread tatsächlich startet, da die Methode submit selbst eine sehr starke Garantie bietet.

Dies ist eine der Funktionen, die das Paket java.util.concurrent sehr nützlich macht.

    
Sergey Tachenov 28.02.2016, 13:38
quelle
1

Dein Freund wäre richtig. Wenn die Variableninitialisierung vor einem Aufruf von Thread.start in der Programmreihenfolge ist, geschieht dies mit JLS 17.4.5 vor dem Thread.start . Der Anfang des Threads erfolgt auch vor der ersten Aktion innerhalb des Threads. Daher passiert es auch - vor dem Aufruf von doStuffWithValue .

Dieser spezielle Fall kann von der JLS allein nicht abgedeckt werden, weil Executor verwendet wird: Sie wissen nicht, wann sie Thread.start für die verwendeten Threads aufruft. Aber von hier können Sie diesen Aufruf lesen submit gibt Ihnen die gleiche Garantie wie Thread.start : Aktionen in einem Thread vor der Übergabe eines Runnable an einen Executor - bevor seine Ausführung beginnt.

Da passiert-bevor ist transitiv, erfolgt die Initialisierung der Variablen vor doStuffWithValue . Das Bit über die Variable, das ein privates Instanzfeld ist, ist jedoch irrelevant.

    
Joni 28.02.2016 13:45
quelle