2016-05-09 2 views
2

Ich war für flüchtige durch die Anwendungsfälle gehen, und ich habe das folgende Szenario auftreten:Multithreading „unberechenbar“ Verhalten

private static boolean stop = false; 
public static void main(String[] args) throws InterruptedException { 
    Thread runner = new Thread(new Runnable() { 

     @Override 
     public void run() { 
      int i = 0; 
      long start = System.currentTimeMillis(); 
      while(!stop){ 
       i++; 
      } 
      System.out.println("I m done after "+(System.currentTimeMillis() - start)); 
     } 
    }); 

    runner.start(); 
    Thread.sleep(2000); 
    stop = true; 
} 

Der obigen Code läuft auf unbestimmte Zeit. Was ist in Ordnung, weil hosten durch den Compiler in einem Versuch, den Code zu optimieren getan. Wenn ich jedoch i ++ durch eine andere Aussage, z. System.out.println ("Hallo"). Es stoppt nach 2 Sekunden.

Warum ist das Verhalten so? Ich benutze jdk1.7.0_51.

Hinweis: Ich weiß, ich sollte Anschlag als flüchtige erklären. Ich möchte jedoch den Grund für das Verhalten in dem obigen Fall wissen.

+0

aus einem lahmen Sicht zunehmende ein Wert ist einfacher als streamen zu schreiben. :). – Elltz

+0

Ein Grund, warum ich mir vorstellen kann, ist, dass i ++ in Java Byte Code konvertiert wird, der keine E/A verwendet, während System.out.println eigentlich E/A ist. Dies kann genug Zeit geben, um die Änderung der boolschen Variablen zu sehen – shazin

Antwort

0

Die Standardausgabe ist eine geteilte Ressource über Threads hinweg. Javas PrintStream Klasse wird thread-safe mit synchronisierten Blöcken gemacht, und alle synchronisierten Blöcke sind Speicherbarrieren in Java, deshalb werden Änderungen auf dem stop Feld innerhalb der Schleife sichtbar. Sie sollten sich jedoch nicht darauf verlassen.

Nehmen wir zum Beispiel einen Blick auf die PrintStream.println Umsetzung:

public void println(String paramString) 
{ 
    synchronized (this) 
    { 
    print(paramString); 
    newLine(); 
    } 
}