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!
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.
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.
Tags und Links java multithreading concurrency