web-dev-qa-db-fra.com

Quelle est la différence entre Thread start () et Runnable run ()

Disons que nous avons ces deux runnables:

class R1 implements Runnable {
    public void run() { … }
    …
}

class R2 implements Runnable {
    public void run() { … }
    …
}

Alors quelle est la différence entre ceci:

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();

    r1.run();
    r2.run();
}

Et ça:

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();
    Thread t1 = new Thread(r1);
    Thread t2 = new Thread(r2);

    t1.start();
    t2.start();
}
206
Ori Popowski

Premier exemple: Pas de threads multiples. Les deux s'exécutent dans un seul thread (existant). Aucune création de fil.

R1 r1 = new R1();
R2 r2 = new R2();

r1 et r2 ne sont que deux objets de classes différents qui implémentent l'interface Runnable et implémentent ainsi la méthode run(). Lorsque vous appelez r1.run(), vous l'exécutez dans le thread actuel.

Deuxième exemple: Deux threads distincts.

Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);

t1 et t2 sont des objets de la classe Thread . Lorsque vous appelez t1.start(), il démarre un nouveau thread et appelle la méthode run() de r1 en interne pour l'exécuter dans ce nouveau thread.

292
Bhesh Gurung

Si vous appelez simplement run() directement, il est exécuté sur le thread appelant, comme tout autre appel de méthode. Thread.start() est nécessaire pour créer un nouveau thread afin que la méthode run du runnable soit exécutée en parallèle.

89
Mike Daniels

La différence est que Thread.start() démarre un thread qui appelle la méthode run(), tandis que Runnable.run() appelle simplement la méthode run() sur le thread actuel.

66
user207421

La différence est que lorsque le programme appelle la méthode start(), un thread new est créé et le code à l'intérieur de run() est exécuté dans new thread alors que vous appelez run() méthode directement pas de nouvea thread sera créé et le code à l'intérieur de run() sera exécuté directement dans le thread actuel.

Un autre différence entre start() et run() dans le fil Java est que vous ne pouvez pas appeler start() deux fois. Une fois démarré, le deuxième appel start() jettera IllegalStateException dans Java pendant que vous pourrez appeler la méthode run() à plusieurs reprises puisqu'il ne s'agit que d'une méthode ordinaire.

30
Jaimin Patel

En fait, Thread.start() crée un nouveau thread et possède son propre scénario d'exécution.

Thread.start() appelle la méthode run() de manière asynchrone, ce qui modifie l'état du nouveau thread en Runnable.

Mais Thread.run() ne crée pas de nouveau fil. Au lieu de cela, il exécute la méthode d'exécution dans le thread en cours d'exécution de manière synchrone.

Si vous utilisez Thread.run(), vous n'utilisez pas du tout les fonctionnalités de multi-threading.

22
aditya

invoke run() est en cours d'exécution sur le thread appelant, comme tout autre appel de méthode. alors que Thread.start() crée un nouveau thread. invoquer run() est un bogue de programmation.

8
Narendra Jaggi

Si vous faites run() dans la méthode main, le thread de la méthode main invoquera la méthode run à la place du thread que vous devez exécuter.

La méthode start() crée un nouveau thread et pour lequel la méthode run() doit être effectuée

6
Rohith

Le code Thread.start() enregistre le thread avec le planificateur et ce dernier appelle la méthode run(). De plus, Thread est une classe alors que Runnable est une interface.

5
CHANDRAHAS

La plupart de ces réponses passent à côté de la vue d'ensemble, à savoir qu'en ce qui concerne le langage Java, il n'y a pas plus de différence entre t.start() et r.run() qu'il n'y en a entre deux autres méthodes.

Ce ne sont que des méthodes. Ils courent tous les deux dans le fil qui les a appelés. Ils font tous les deux ce pour quoi ils ont été programmés, puis ils retournent tous les deux, toujours dans le même fil, à leurs appelants.

La plus grande différence réside dans le fait que la plupart du code pour t.start() est natif alors que, dans la plupart des cas, le code pour r.run() sera en Java pur. Mais ce n'est pas une grande différence. Le code est le code. Le code natif est plus difficile à trouver, et plus difficile à comprendre quand vous le trouvez, mais c'est toujours du code qui indique à l'ordinateur quoi faire.

Alors, que fait t.start()?

Il crée un nouveau thread natif, il fait en sorte que ce thread appelle t.run(), puis il demande au système d'exploitation de laisser le nouveau thread s'exécuter. Puis ça revient.

Et que fait r.run()?

La chose amusante est que la personne qui pose cette question est celle qui l'a écrite. r.run() fait tout ce que vous (c'est-à-dire le développeur qui l'a écrit) l'a conçu pour le faire.


t.start() est la méthode fournie par la bibliothèque pour que votre code appelle lorsque vous voulez un nouveau thread.

r.run() est la méthode que vous fournissez à la bibliothèque pour appeler in le nouveau thread.

4
Solomon Slow

Les points soulevés par les membres sont corrects, alors je veux juste ajouter quelque chose. Le fait est que Java ne prend en charge aucun héritage multiple. Mais que se passe-t-il si vous voulez dériver une classe B d'une autre classe A, mais que vous ne pouvez dériver que d'une classe. Le problème est maintenant de savoir comment "dériver" des deux classes: A et Thread. Par conséquent, vous pouvez utiliser l'interface Runnable.

public class ThreadTest{
   public void method(){
      Thread myThread = new Thread(new B());
      myThread.start;
   }
}

public class B extends A implements Runnable{...
3
pommoisel

Si vous appelez directement la méthode run(), vous n'utilisez pas la fonction multi-threading, car la méthode run() est exécutée dans le cadre du thread appelant.

Si vous appelez la méthode start() sur le thread, la machine virtuelle Java appellera la méthode run () et deux threads seront exécutés simultanément - Thread actuel (main() dans votre exemple) et Other Thread (Runnable r1 dans votre exemple).

Regardez le code source de la méthode start() dans classe de threads

 /**
     * 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();

Dans le code ci-dessus, vous ne pouvez pas voir l'invocation de la méthode run().

private native void start0() est responsable de l'appel de la méthode run(). JVM exécute cette méthode native.

2
Ravindra babu

Dans le premier cas, vous appelez simplement la méthode run() des objets r1 et r2.

Dans le second cas, vous créez 2 nouveaux threads!

start() appellera run() à un moment donné!

1
Gevorg