web-dev-qa-db-fra.com

Quand appelleriez-vous le thread.run () de Java au lieu de thread.start ()?

Quand appelleriez-vous la thread.run() de Java au lieu de thread.start()?

107
blank

Vous voudrez peut-être appeler run () dans un test unitaire particulier qui concerne strictement la fonctionnalité et non la concurrence.

110
Paul Croarkin

Jamais. L'appel de run () exécute directement le code de manière synchrone (dans le même thread), tout comme un appel de méthode normal.

94
Adam Crume

Pris sous la forme Style de code Java :

Q: Quelle est la différence entre les méthodes start () et run () d'un thread?

R: Les méthodes start () et run () distinctes de la classe Thread offrent deux façons de créer des programmes filetés. La méthode start () démarre l'exécution du nouveau thread et appelle la méthode run (). La méthode start () renvoie immédiatement et le nouveau thread continue normalement jusqu'à ce que la méthode run () revienne.

La méthode run () de la classe Thread ne fait rien, les sous-classes doivent donc remplacer la méthode par du code à exécuter dans le deuxième thread. Si un thread est instancié avec un argument Runnable, la méthode run () du thread exécute à la place la méthode run () de l'objet Runnable dans le nouveau thread.

Selon la nature de votre programme threadé, l'appel direct de la méthode Thread run () peut donner la même sortie que l'appel via la méthode start (), mais dans ce dernier cas, le code est en fait exécuté dans un nouveau thread.

27
Tomalak

L'exécution de thread.run() ne crée pas de nouveau Thread dans lequel votre code sera exécuté. Il exécute simplement le code dans le thread actuel à partir duquel le code thread.run() est appelé.

L'exécution de thread.start() crée un nouveau thread de niveau OS dans lequel la méthode run() est appelée.

En substance:

Programmation Single Threaded → Appel direct de la méthode run()

Programmation multithread → Appel de la méthode start()

De plus, comme d'autres l'ont mentionné, le "test" semble être le seul cas conseillé dans lequel vous pouvez invoquer run() directement à partir de votre code.

23
Mahendra Liya

Cela a déjà été fait allusion, mais juste pour être clair: créer un nouvel objet Thread uniquement pour appeler sa méthode run () est inutilement cher et devrait être un drapeau rouge majeur. Ce serait une conception bien meilleure et plus découplée pour créer un implément Runnable et soit (a) appeler c'est la méthode run () directement si c'est le comportement souhaité, ou (b) construire un nouveau Thread avec cela Exécutable et démarrez le fil.

Mieux encore, pour encore plus de découplage, consultez l'interface et le framework Executor dans JDK 5 et plus récent. Cela vous permet, en un mot, de découpler l'exécution de la tâche (l'instance Runnable) de comment elle est exécutée (l'implémentation Executor, qui pourrait exécuter Runnable dans le thread actuel, dans un nouveau thread, en utilisant un thread existant d'un pool, et ainsi de suite).

13
Scott Bale

Les méthodes start() et run() distinctes de la classe Thread offrent deux façons de créer des programmes filetés. La méthode start() démarre l'exécution du nouveau thread et appelle la méthode run(). La méthode start() retourne immédiatement et le nouveau thread continue normalement jusqu'à ce que la méthode run() revienne.

La méthode Thread class ’run() ne fait rien, les sous-classes doivent donc remplacer la méthode par du code à exécuter dans le deuxième thread. Si un thread est instancié avec un argument Runnable, la méthode run() du thread exécute à la place la méthode run() de l'objet Runnable dans le nouveau thread.

Selon la nature de votre programme threadé, l'appel direct de la méthode Thread run() peut donner la même sortie que l'appel via la méthode start(), mais dans ce dernier cas, le code est en fait exécuté dans un nouveau fil.

référence

9
alok

Appelez thread.start(), elle appellera à son tour thread.run(). Je ne peux pas penser à un cas où vous voudriez contourner thread.start() et aller directement à thread.run()

9
Chris Ballance

Si la question était - "pourquoi la méthode de démarrage du thread est appelée au lieu de la méthode d'exécution directement", j'ai répondu avec un exemple de code ci-dessous. J'espère que cela clarifie. Dans l'exemple ci-dessous:

/*
By calling t1.start(), 
we are getting the main calling thread returned immediately 
after the t1.start() called and is ready to proceed for other 
operations.And the thread t1 starts executing the run method of the object r. 
Hence the the output will be:

      I am the main thread , i created thread t1 and had it execute run method, which is currently looping from 0 to 1000000

      I am done executing run method of testThread

*/


/* If we call t1.run() instead of t1.start(), (just replace t1.start() with t1.run() in the code for testing)
 its like a regular method call and the main thread will not return until the run method completes, 
 hence the output will be:

         I am done executing run method of testThread

         I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000

*/


class testThread implements Runnable{

 public void run()
 {
     for(int i=0;i<1000000;i++){} //a simple delay block to clarify.

     System.out.println("I am done executing run method of testThread");

 }  
}

public class mainClass{

   public static void main(String [] args)
    {
          testThread r = new testThread();
          Thread t1 = new Thread(r);
          t1.start();  /* Question is: can we call instead t1.run() */  
          System.out.println("I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000");

    }
}
7
Steer360

Lorsque vous souhaitez qu'il fonctionne de manière synchrone. L'appel de la méthode run ne vous donnera pas réellement de multi-threading. La méthode start crée un nouveau thread qui appelle la méthode run.

5
Brian

Si vous souhaitez exécuter le contenu de run () comme vous le feriez pour toute autre méthode. Pas pour démarrer un fil, bien sûr.

3
Don

En supposant que vous connaissez l'utilisation de la méthode de démarrage et d'exécution, c'est-à-dire synchrone vs asynchrone; La méthode run peut être utilisée uniquement pour tester la fonctionnalité.

De plus, dans certaines circonstances, la même classe de threads peut être utilisée à deux endroits différents avec des exigences de fonctionnalité de synchronisation et d'asynchronisation en ayant deux objets différents avec la méthode run et la méthode start de l'autre étant invoquées.

3
Salman Kasbati

Juste une note aux grands commentaires ci-dessus: parfois, vous écrivez un code multi-thread qui utilise la méthode "start" pour exécuter différents threads. Vous le trouverez beaucoup plus facile si vous utilisez "run" (au lieu de "start" pour le débogage car cela rend le code à exécuter de manière synchrone et le débogage beaucoup plus facile.

2
msamadi

Au moins dans la JVM 1.6., Il y a un peu de vérification et l'exécution est appelée nativement:

 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();
2
Steve B.