web-dev-qa-db-de.com

Warum rufen wir die Methode Thread.start () auf, die wiederum run-Methode aufruft?

Warum rufen wir die start()-Methode des Thread-Objekts auf, die wiederum run()-Methode aufruft, warum rufen wir nicht direkt die run()-Methode auf?

36
Anu

[...] warum rufen wir die run () - Methode nicht direkt auf?

Die run()-Methode ist nur eine gewöhnliche Methode (überschrieben durch Sie). Wie bei jeder anderen gewöhnlichen Methode führt der direkte Aufruf des aktuellen Threads dazu, run() auszuführen.

Alle Magie geschieht in start(). Die start()-Methode bewirkt, dass die JVM einen neuen Thread erstellt und den neu erstellten Thread zur Ausführung von run() veranlasst.

61
aioobe

Wenn Sie die run () -Methode direkt aufrufen, wird ihr Rumpf im Kontext des aktuellen Threads ausgeführt. Wenn Sie die start()-Methode aufrufen, wird ein neuer Thread erstellt und die run()-Methode wird in diesem neuen Thread ausgeführt.

24
AlexR

Selbst wenn wir programmgesteuert keinen Thread erstellen, erstellt O.S für jede Anwendung einen Standard-Thread, um den Code mit CPU auszuführen.

Beim direkten Aufruf der run-Methode wird diese run-Methode in dem von O.S. angegebenen Haupt-Thread ausgeführt.

Das Erstellen einer Thread-Klasse soll jedoch sicherstellen, dass die run-Methode in einem anderen Thread ausgeführt wird. Wenn der Thread-Manager von O.S keinen Thread erstellt, wird Ihre Laufmethode nicht in einem separaten Thread ausgeführt. Um O.S zur Erstellung eines separaten Threads anzufordern, müssen Sie die start () - Methode aufrufen, die eine Anfrage an OS sendet, um einen Thread zu erstellen. Nachdem O.S einen Thread erstellt hat, ruft O.S automatisch die Run-Methode Ihrer Thread-Klasse in diesem neu erstellten Thread-Kontext auf. Daher wird Ihr Zweck erfüllt, einen separaten Thread zu erstellen und Ihre Laufmethode in einem separaten Thread auszuführen.

Wenn Sie die run-Methode direkt aufrufen, ist es, als würde O.S keinen Thread für Sie erstellen, und der standardmäßige Haupt-Thread führt Ihre run-Methode aus. Es macht keinen Sinn, dafür eine eigene Thread-Klasse zu erstellen!

Hoffe ich bin klar. Lassen Sie mich wissen, wenn Sie weitere Erklärungen benötigen, um Ihre Frage zu beantworten.

Anmerkung: Obwohl in Büchern von JVM die Erstellung von Threads erwähnt wird, muss die JVM intern eine Anforderung an den Thread-Manager-Treiber der O.S-Schicht senden, um einen neuen Thread in ihrem Thread-Pool zu erstellen. Aus diesem Grund verwende ich hier mehr als JVM.

16
user1923551

Warum rufen wir die start () - Methode des Thread-Objekts auf, die wiederum Aufrufe von run () -Methode

Nein, tut es nicht. start() ruft das Betriebssystem auf, das einen neuen Thread startet, der (zur Vereinfachung) die run()-Methode aufruft. Inzwischen ist die start()-Methode bereits zu ihrem Aufrufer zurückgekehrt. Sie sind nicht gleichwertig.

9
user207421

Runnable ist nur eine Schnittstelle. Eine Klasse, die Runnable implementiert, ist nichts Besonderes, sie hat nur eine run-Methode.

Thread#start ist eine nativ implementierte Methode, die einen separaten Thread erstellt und die Thread-Methode der Variable run aufruft, die den Code im neuen Thread ausführt.

Thread implementiert Runnable. Der Code für run sieht folgendermaßen aus:

@Override
public void run() {
    if (target != null) {
        target.run();
    }
}

Wenn die Thread-Instanz durch Übergeben einer Runnable an den Konstruktor der Thread erstellt wurde, wird die Runnable-Methode der run aufgerufen.

Andernfalls müssen Klassen, die Thread erweitern, die run-Methode überschreiben, damit start funktionieren kann.

Beim Aufruf von run für Thread wird KEIN neuer Thread erstellt.

8
Jonathon Faust

Wenn ein Thread instanziiert, aber noch nicht gestartet wurde, wird gesagt, dass er sich im neuen Zustand befindet. 
Wenn nicht eine start () -Methode für die Instanz des Threads aufgerufen wird, wird sie nicht als lebend bezeichnet.
Wenn Sie in der neu erstellten Thread-Instanz keine start () -Methode aufrufen, wird der Thread als nicht lebend betrachtet.
Wenn die start () -Methode nicht aufgerufen wird und die run () -Methode direkt in der Thread-Instanz aufgerufen wird, wird der Code in der run () -Methode nicht in einem separaten neuen Thread ausgeführt, sondern in dem vorhandenen Thread .

SEHEN SIE DAS PROBLEM IM BEISPIEL

class Multi extends Thread{  
 public void run(){  
  for(int i=1;i<5;i++){  
    try{Thread.sleep(500);}catch(InterruptedException e){System.out.println(e);}  
    System.out.println(i);  
  }  
 }  
 public static void main(String args[]){  
  Multi t1=new Multi();  
  Multi t2=new Multi();  

  t1.run();  
  t2.run();  
 }  
}  

Output:1
       2
       3
       4
       5
       1
       2
       3
       4
       5

Wie Sie im obigen Programm sehen können, gibt es keine Kontextumschaltung, da hier t1 und t2 als normales Objekt und nicht als Threadobjekt behandelt werden.

4
VdeX

Ich nehme an, Sie sprechen davon, einen Thread zu beginnen. Wenn dies der Fall ist, besteht der Grund dafür, dass Sie die run-Methode nicht direkt aufrufen, darin, dass Sie die Methode aufrufen und den Thread nicht starten. 

1
Goibniu

Dies liegt am Design von Multithreading in Java.

Beim Aufruf von start () wird ein neuer Thread gestartet, und beim Aufruf der run()-Methode wird kein neuer Thread gestartet.

Wenn Sie die start()-Methode für Thread aufrufen, ruft die Java Virtual Machine die run () - Methode auf, und zwei Threads werden jetzt gleichzeitig ausgeführt - Current Thread und Other Thread oder Runnable-Implementierung.

Sehen Sie sich den Quellcode der start()-Methode in Thread-Klasse an.

 /**
     * Causes this thread to begin execution; the Java Virtual Machine
     * calls the <code>run</code> method of this thread.
     * <p>
     * The result is that two threads are running concurrently: the
     * current thread (which returns from the call to the
     * <code>start</code> method) and the other thread (which executes its
     * <code>run</code> method).
     * <p>
     * It is never legal to start a thread more than once.
     * In particular, a thread may not be restarted once it has completed
     * execution.
     *
     * @exception  IllegalThreadStateException  if the thread was already
     *               started.
     * @see        #run()
     * @see        #stop()
     */
    public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        group.add(this);
        start0();
        if (stopBeforeStart) {
            stop0(throwableFromStop);
        }
    }

    private native void start0();

Im obigen Code wird der Aufruf der run()-Methode nicht angezeigt. 

private native void start0() ist für den Aufruf der run()-Methode verantwortlich. JVM erstellt einen eigenen Thread, der dem Java-Thread entspricht, und ruft die run()-Methode auf.

In dieser Frage finden Sie Quellcode für native Methoden:

Wo finde ich Quellcode für native Java.lang-Methoden?

1
Ravindra babu

Wenn wir die Startmethode verwenden, wird ein neuer Thread erstellt, und dann wird für jeden neuen Thread Code innerhalb der Laufmethode ausgeführt.

Bei Verwendung der Startmethode werden zwei Stapel für jeden Thread, Stapel und nativen Stapel erstellt.

Aber Run Methodenaufruf execute Der Code innerhalb der run-Methode erstellt sequentiell als run-Methodenaufruf keine unterschiedlichen Stapel.

Beispiel

import Java.util.concurrent.TimeUnit;

public class thread implements Runnable{

    /**
     * @param args
     */
    public static void main(String[] args) {
        Thread gg=new Thread(new thread());
        Thread gg1=new Thread(new thread());
        gg.run();
        gg1.start();
        /*gg.start();
        gg1.start();*/

    }

    @Override
    public void run() {
        for(int i=0;i<5;i++)
        {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        System.out.println("Hello..." + i);
        }

    }

}
1
Rohit Yadav

start()- und run()-Methoden werden zum Ausführen eines Threads verwendet. Die run()-Methode ist nur eine gewöhnliche Methode, sie wird vom Benutzer überschrieben und im aktuellen Thread aufgerufen. Die start()-Methode führt indirekt die run()-Methode aus und erstellt eine neues Thema. 

0
Lokesh Kumar

Wenn wir wollen, können wir die run()-Methode aufrufen, aber wenn wir die run-Methode aufrufen, wird sie als normale Java-Methode ausgeführt. Während wir start() nennen, erstellt JVM einen neuen Thread und die Run-Methode wird in diesem Thread ausgeführt. 

0
Upul Bandara