2016-07-07 11 views
-1

Ich habe den folgenden Code:Wie läuft der Haupt-Thread vor diesem Thread?

public class Derived implements Runnable { 
     private int num; 

     public synchronized void setA(int num) { 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
      } 
      System.out.println("Setting value " + Thread.currentThread().getName()); 
      this.num = num; 
     } 

    @Override 
    public void run() 
    { 
     System.out.println("In run: " + Thread.currentThread().getName()); 
     setA(20); 
    } 

     public static void main(String[] args) { 
      Derived obj = new Derived(); 
      Thread t1 = new Thread(obj); 
      t1.start(); 
      obj.setA(32); 
     } 
    } 

Diese Drucke:

In run: Thread-0 
Setting value main 
Setting value Thread-0 

Meine Frage ist, wenn ich den Faden ‚t1‘ zuerst, und es trat in die run-Methode wie die Ausgabe zeigt der Autor, wie come main thread konnte setA vor 't1' aufrufen, wenn das Objekt von t1 gesperrt wurde? (oder sogar bevor eine Sperre auf 'obj' main konnte eine Sperre bekommen) Ist es nur der Scheduler oder denke ich es falsch?

+1

Es gibt keine Garantien über die Bestellung mit Threads, es sei denn, Sie nehmen explizite Schritte, um sie zu synchronisieren. Das ist der springende Punkt von Threads, sie sind asynchron. –

+1

Der Haupt-Thread läuft bereits, wenn dieser Code aufgerufen wird. Ihr anderer Thread wird nur ein bisschen Zeit brauchen, um aufgebaut und ausgeführt zu werden, und so bin ich nicht überrascht über das Ergebnis, das Sie sehen. Plus was @JimGarrison oben gesagt hat. –

+0

Ihr Code sollte auch nicht kompilieren - Sie haben eine Runnable ohne 'run()' Methode. –

Antwort

3

Wie kann der Haupt-Thread SetA vor 't1' aufrufen, wenn das Objekt von t1 gesperrt wurde?

Der ganze Sinn der Verwendung mehrerer Threads besteht darin, dass Code in jedem Thread unabhängig ausgeführt werden kann. Die Thread.start() (oder eine andere Methode) ist nicht sofort. Es braucht Zeit und während der Thread gestartet wird, können Sie Code in Ihrem aktuellen Thread ausführen, er kann sogar vollständig ausgeführt werden, bevor der Hintergrund-Thread überhaupt gestartet wird.

Ist es nur die

Scheduler, ein Teil davon ist. Aber es ist auch die Tatsache, dass das Starten eines Threads nicht frei ist und eine nicht-triviale Menge an Zeit benötigt.

public class Test { 
    public static void main(String[] args) { 
     long start = System.nanoTime(); 
     new Thread(() -> System.out.println("Thread took " + 
       (System.nanoTime() - start)/1e6 + " ms to start")) 
       .start(); 
    } 
} 

Ich habe eine schnelle Maschine, aber wenn ich dieses Programm starte, dauert der erste Thread eine Weile.

Thread took 44.695419 ms to start 
+0

Danke für die Antwort @ Peter.Große Erklärung. Was ich versuchte, war, wenn ein Thread eine synchronisierte Methode eingibt, kein anderer Thread kann irgendwelche synchronisierten Methoden des Objekts eingeben, selbst wenn ich den Thread schlafen lasse. Habe ich recht? Kann ein anderer Thread auch einen nicht-synchronisierten Code eingeben, der auf die Klassendaten zugreift? – Kode

+1

@Vwin korrekt über synchronisiert und Schlaf, beachten Sie: Wenn Sie warten() stattdessen, kann ein anderer Thread die Sperre erhalten. Eine beliebige Anzahl von Threads kann eine Methode ausführen, wenn sie nicht synchronisiert ist. –

+0

Großartig. Danke für die Hilfe – Kode