sich das folgende Szenario aus Memory Consistency - happens-before relationship in Java entlehnt:Konnte Java thread.start neu geordnet werden?
package happen.before;
public class HappenBeforeRelationship {
private static int counter = 0;
private static void threadPrintMessage(String msg){
System.out.printf("[Thread %s] %s\n", Thread.currentThread().getName(), msg);
}
public static void main(String[] args) {
threadPrintMessage("Increase counter: " + ++counter);
Thread t = new Thread(new CounterRunnable());
t.start();
try {
t.join();
} catch (InterruptedException e) {
threadPrintMessage("Counter is interrupted");
}
threadPrintMessage("Finish count: " + counter);
}
private static class CounterRunnable implements Runnable {
@Override
public void run() {
threadPrintMessage("start count: " + counter);
counter++;
threadPrintMessage("stop count: " + counter);
}
}
Ich weiß, es gibt eine Regel in JLS garantiert, dass Thread.start
vor allen Aktionen im gestarteten Thread passiert.
Wenn eine Anweisung ruft Thread.start, jede Aussage, die auch mit dieser Aussage eine passiert-vor-Beziehung hat eine passiert-vor-Beziehung mit jedem von dem neuen Thread ausgeführten Anweisung. Die Auswirkungen des Codes, der zur Erstellung des neuen -Threads führte, sind für den neuen Thread sichtbar.
Aber es behauptet nicht, dass Aussagen vor Thread.start
eine passiert-vor-Beziehung damit hat.
Also frage ich mich, dass könnte Thread.start
neu geordnet werden, so dass das Programm nicht die erwartete Ausgabe erhalten konnte (Zähler = 2)? Wenn nicht, welcher Teil von JLS gibt an, dass Thread.start
nicht nachbestellt werden konnte?
Eine weitere Frage:
Was passiert, wenn join()
nach threadPrintMessage("Finish count: " + counter);
gesetzt wird? Ist es möglich, dass stop count: 1
gedruckt wird?
Unabhängig von der Neuordnung des Starts ist die Ausgabe nicht unbedingt 2, da die Sichtbarkeit von Aktualisierungen des Zählers nicht garantiert ist. –
@AndyTurner, könnten Sie die zweite Antwort in http://stackoverflow.com/questions/16248898/memory-consistency-happens-before-relationship-in-java überprüfen? Es weist darauf hin, dass 'JLS garantiert, dass das Aufrufen von t.start() die Änderung von x in t.run() sichtbar macht, so dass y garantiert 1 'zugewiesen wird, also ist es eine falsche Aussage? –
@ Chainro das ist definitiv richtig. Von oben nach unten, wie gesagt. Vor dem 'Thread.start' sind Sie single-threaded, so dass die natürliche Reihenfolge respektiert wird. – Dici