2016-08-04 10 views
-1

Hallo Ich versuche, die Ausgabe des untenstehenden Codes zu verstehen. Nach meinem Verständnis kann die Ausgabe für First und Second Thread unterschiedlich sein.Aber wenn ich den unten genannten Code ausgeführt habe, bekomme ich oft noch der gleiche Wert für beide Thread.Kann jemand bitte etwas Licht werfen, ob ich falsch oder richtig bin.Ausgabe eines Multithread-Programms

package com.vikash.Threading; 

public class ThreadLocalExample { 

    public static class MyRunnable implements Runnable { 

     @SuppressWarnings("unused") 
     private ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); 
     D d=new D(); 

     @Override 
     public void run() { 
      //threadLocal.set((int) (Math.random() * 100D)); 
      d.setX((int) (Math.random() * 100D)); 
      //System.out.println(Thread.currentThread().getName()+" "+threadLocal.get()); 
      System.out.println(Thread.currentThread().getName()+" "+d.getX()); 
      try { 
       Thread.sleep(200); 
      } catch (InterruptedException e) { 
      } 
      //System.out.println(Thread.currentThread().getName()+" "+threadLocal.get()); 
      //System.out.println(Thread.currentThread().getName()+" "+d.getX()); 
     } 
    } 

    public static void main(String[] args) throws InterruptedException { 

     MyRunnable sharedRunnableInstance = new MyRunnable(); 

     Thread thread1 = new Thread(sharedRunnableInstance); 
     Thread thread2 = new Thread(sharedRunnableInstance); 

     thread1.start();thread1.setName("First"); 
     thread2.start();thread2.setName("Second");; 

     thread1.join(); //wait for thread 1 to terminate 
     thread2.join(); //wait for thread 2 to terminate 
    } 
} 
+0

@Vikash gedruckt: der Code fehlt Synchronisation, was bedeutet, dass, formal, werden die Ergebnisse nicht vollständig spezifiziert. Mit anderen Worten, Sie haben keine Garantie, was die Ergebnisse sein werden. Sie haben jedoch auch keine Garantie, dass * Sie unterschiedliche Ergebnisse sehen, wenn Sie sie mehrmals ausführen. Es kann vorkommen, dass in Ihrem speziellen System, in Ihrer speziellen JVM-Version, Java-Compiler usw. * möglicherweise * immer dieselben Ergebnisse angezeigt werden. Aber noch einmal: Formal ausgedrückt (dh gemäß den JVM-Spezifikationen) ist Ihr Code nicht für bestimmte Ergebnisse garantiert. –

+0

@Vikash: Das einzige, was Sie sich selbst "beweisen" können, indem Sie mehrmals laufen, ist: Wenn Sie unterschiedliche Ergebnisse sehen, haben Sie * Beweise * für den Mangel an Synchronisation. Wenn Sie jedoch mehrere Male ausgeführt werden und immer die gleichen Ergebnisse sehen, haben Sie keine Beweise. Es ist wirklich schwierig, Synchronisationsprobleme zu testen! –

Antwort

1

Dies ist, weil Sie nicht auf d Synchronisation sind, so was Faden 1 Sätze X-Wert ist passiert, dann 2 Sätze x-Wert Gewinde, Gewinde dann 1 druckt Wert, der bereits von Thread 2. Synchronisieren Block Marken zurückgesetzt wurde sicher, dass der richtige Wert

synchronized (d) { 
    d.setX((int) (Math.random() * 100D)); 
    System.out.println(Thread.currentThread().getName() + " " + d.getX()); 
} 
+1

(Verdammt, ich habe meinen Kommentar versehentlich verloren, als ich versucht habe, mehr Text einzufügen und neu zu schreiben) Das Feld "d" wird initialisiert, bevor beide Threads gestartet werden, also gibt es hier eine "happen-before" -Beziehung. Nichts ändert jemals das Feld "d" nach dieser Initialisierung. Dies bedeutet, dass beide Threads garantiert das korrekt initialisierte Feld "d" lesen. Das Hinzufügen von 'volatile' ändert nichts: das einzige, was volatile tut, ist das Errichten geschieht-vor Beziehungen von Schreibvorgängen zu dem flüchtigen Feld, gefolgt von Lesevorgängen des gleichen flüchtigen Feldes. –

+0

@BrunoReis du hast recht, das volatile ist hier nicht genug. Bearbeitete meine Antwort entsprechend. Danke, dass du darauf hingewiesen hast – noscreenname