2017-12-30 44 views
0

Jetzt gibt es gute Antworten auf diese bereits auf Stackoverflow, aber sie geben mir nicht die endgültige Antwort, die ich will.Ist alles, was vor thread.start passiert ist, für den erstellten Thread sichtbar? Callimg start?

Sagen Sie eine Methode

Dosomething(); 
doAnother(); 
    int x = 5; 
    Runnable r = new Runnable(){ 
    public void run(){ 
    int y = x; 
    x = 7; 
    System.out.println(z);} 
    } 
    new Thread(r).start() 

Jetzt kommt diese Methode inzwischen läuft und vor Thread.start Aufruf, einige globale nichtflüchtigen Variablen z geändert wurde 5 von 4.

Würde das Programm sein garantiert 5 zu drucken, da z vor thread.start passiert ist?

Auch wenn wir darüber reden, dann ist es sicher zu sagen, dass thread.start() niemals jemals nachbestellt werden kann.

Bedeutung in Bezug auf diesen Thread, der Start aufgerufen wird, ist es, als ob alles bis zu diesem Punkt sequenziell ist. Zum Beispiel sagen wir

int k = 8; 
new Thread(() -> {}).start() 

Jetzt haben ... Es würde nicht einen Unterschied in der Perspektive dieses Themas machen, ob der Start zuerst aufgerufen wird oder k zugeordnet 8. So können diese neu geordnet werden, sondern wegen der geschieht vor der Garantie, ist das nicht möglich?

Die Java-Spezifikationen sagen nicht eine starke Aussage, die das sagt. Vielmehr sagt er

Wenn eine Anweisung Thread.start() aufruft, jede Aussage, die mit dieser Aussage

jedoch k = 8 nicht, dass ein vor Beziehung geschieht mit dieser Aussage ein geschieht zuvor Beziehung hat ...

im nicht einmal sicher, ob sie das, was etwas zu bedeuten hat ein geschieht, bevor Beziehung mit der Startmethode, wenn Sie zum Beispiel mit dem gleichen Monitor gesperrt

synchronized(this){ int k = 8;} 
synchronized(this) { new Thread(() -> {}).start();} 

für einen erschreckenden Fall, was wir diesen Code hatten

Socket con = socket.accept(); 
Runnable r = new Runnable(){ 
    public void run(){ 
     handleRequest(con)} 
} 
new Thread(r).start(); 

Und dann der neue Thread passiert, dass Con null sein?

Kann mir jemand eine definitive Antwort zu diesen Themen geben?

+0

Haben Sie diesen Thread gesehen? https://stackoverflow.com/questions/7128662/does-a-thread-start-causes-a-memory-barrier-shared-variables-will-be- –

+0

Ja, aber ich denke, ich wollte mehr Bestätigung geben die Beispiele Ich gab, seit ich es schwer hatte, andere Gedanken zu interpretieren. Trotzdem schätzen Sie den Link – katiex7

Antwort

2

Wäre das Programm garantiert 5 zu drucken, da z vor thread.start passiert ist?

Wenn der Wert von z durch den Thread festgelegt wurde, der die Methode start() aufgerufen hat, dann yes. Ansonsten, nein. Der neu gestartete Thread sieht garantiert die Änderungen des Threads, der ihn gestartet hat, NICHT die von anderen Threads gemachten Änderungen.

Auch wenn wir darüber reden, dann ist es sicher zu sagen, dass thread.start() niemals jemals nachbestellt werden kann.

Der Punkt ist - der neu gestartete Thread ist garantiert, den Wert von k als 8 zu sehen.Wenn der neu gestartete Thread k nicht liest (oder andere Variablen, die vom übergeordneten Thread gesetzt wurden), können Compiler diese Operationen neu anordnen, aber das ist dem Programmierer egal (der Programmierer erhält die Garantie trotzdem)

Und dann der neue Thread passiert, dass Con null sein?

Unter der Annahme, dass der neue Thread einen Verweis auf con hat, con garantiert wird, bevor die neuen Thread startet initialisiert werden (da die JMM garantiert, dass alle von dem Muttergewinde vor dem Aufruf vorgenommenen Änderungen() zu starten wäre (für den neuen Thread sichtbar)

Zusammengefasst - ist ein Thread (T1) startet einen anderen Thread (T2), dann sind alle von T1 vorgenommenen Änderungen vor T2 zu T2 sichtbar garantiert werden. Als Programmierer zählt das. Compiler dürfen Neubestellungen durchführen, solange sie diese Garantie nicht überschreiten. Sie könnten natürlich auf die JLS verweisen, aber ich denke, Sie haben bereits.

+0

Sweeet. Das ist, was ich gesucht habe. Wie wäre es damit? In dem Thread, der den neuen Thread erzeugt, sagen wir, dass wir int x = someGlobalVariable hatten. Dann verwendet es im neuen Thread x. Ist x garantiert der letzte Wert einer GlobalVariable, als wäre eine GlobalVariable volatil? – katiex7

+0

Nop. Happens-before ist transitiv. Also wenn (und nur wenn) die Operation, die einigeGlobalVariable gesetzt hatte, eine Vor-Vor-Beziehung mit int x = etwasGlobalVariabel hatte, dann hätten Sie diese Garantie gehabt. Andernfalls, wenn einigeGlobalVariable von einem anderen zufälligen Thread festgelegt wurde, erhalten Sie diese Garantie nicht. –

+0

Ehrfürchtig. Ich liebe es, wie du Dinge antwortest. Es ist definitiv. – katiex7