2008-11-04 8 views
105

¿Cuándo llamarías a Java thread.run() en lugar de thread.start()?¿Cuándo llamarías a thread.run() de java en lugar de thread.start()?

+45

cuando estoy en el hilo.start() método? :) –

+3

@blank, la respuesta es simplemente: 't.run()' cuando desea ejecutar la tarea 't' en el hilo actual, y' t.start() 'cuando desea ejecutar' la tarea de t' en la rosca 't' sí. O estás pidiendo casos de uso reales? – Pacerier

+1

Cuando eres idiota y se desea pasar una hora depuración de código multiproceso sólo para darse cuenta más tarde que sólo debería haber llamado' start() '! Me gusta ... Este método no debe ser público! –

Respuesta

109

Es posible que desee llamar a run() en una prueba de unidad particular que se refiere estrictamente a la funcionalidad y no a la concurrencia.

9

Llamada thread.start(), a su vez llamará thread.run(). No se puede pensar en un caso en el que desea omitir thread.start() e ir directamente al thread.run()

+3

Durante las pruebas es el único caso legítimo que se me ocurre. De lo contrario, los contenidos de run() deberían estar en un método separado que se ejecuta mediante run, o de otra manera. –

93

Nunca. Llamar a ejecutar() directamente solo ejecuta el código de forma síncrona (en el mismo hilo), al igual que una llamada a método normal.

+23

"Nunca" es un poco demasiado absoluto. ¿Tal vez no siempre quiera un hilo nuevo y todavía ejecute el código? – Tomalak

+4

Quizás, pero en ese caso sería innecesariamente innecesario crear un nuevo subproceso solo para llamar al método run(). Es mejor crear una impl Runnable y ejecutarla en subproceso o construir y comenzar un nuevo subproceso con ella. –

+0

Absolutos generalmente son demasiado fuertes, pero una vez más, las reglas están hechas para romperse. Creo que mantenerlo claro y simple es lo mejor, especialmente para los programadores principiantes. Además, este caso es bastante corto. Scott Bale lo clavó cuando sugirió usar Runnable. –

5

Cuando quiere que se ejecute sincrónicamente. Llamar al método de ejecución en realidad no le dará múltiples subprocesos. El método de inicio crea un nuevo hilo que llama al método de ejecución.

27

tomado forma la Code Style Java threads FAQ:

Q: ¿Cuál es la diferencia entre() los métodos de inicio de un hilo () y correr?

A: Los métodos start() y run() separados en la clase Thread proporcionan dos formas de crear programas enhebrados. El método start() inicia la ejecución del nuevo hilo y llama al método run() . El método start() devuelve inmediatamente y la nueva cadena normalmente continúa hasta que el método run() retorna.

El método de la clase Thread 'run() no hace nada, por lo que las subclases deben anular el método con el código ejecutar en el segundo hilo. Si un subproceso se crea una instancia con un argumento Ejecutable , el método run() del subproceso ejecuta el método run() del objeto Runnable en el nuevo subproceso .

Dependiendo de la naturaleza de su programa de roscado, llamando al hilo método run() directamente puede dar la misma salida que llama a través de la start() método, pero en este último caso el código es realmente ejecutado en un nuevo hilo .

+0

'método de hilo de ejecución() ejecuta el método run() del objeto Ejecutable en el nuevo hilo instead.' Eso no es verdad (o por lo menos mi código fuente de Java 8 dice lo contrario), pero desafortunadamente el enlace parece roto, así que informa el error aquí en su lugar. – kajacx

+1

@Tomalak, Esto no responde la pregunta. La pregunta no es preguntar la diferencia, sino preguntar sobre casos de uso por los cuales llamaremos 'thread.run()' en lugar de 'thread.start()'. – Pacerier

3

Si desea ejecutar los contenidos de run() como lo haría con cualquier otro método. No para comenzar un hilo, por supuesto.

3

Suponiendo que conoce el uso del método de inicio y ejecución, es decir, sincrónico vs. asincrónico; El método run se puede usar solo para probar la funcionalidad.

Además, en algunas circunstancias, la misma clase de subprocesos se puede usar en dos lugares diferentes con requisitos de funcionalidad de sincronización y asincronización al tener dos objetos diferentes con el método de ejecución y el método de inicio de otros invocados.

2

Al menos en la JVM 1.6., Hay un poco de cheques y de ejecución se llama de forma nativa:

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(); 
13

Esto ya se ha aludido, pero sólo para ser claros: la creación de un nuevo objeto Thread sólo para llamada Se método run() es innecesariamente caro y debe ser una gran bandera roja. Sería un diseño mucho mejor y más desacoplado crear una ejecución Runnable y (a) llamar al es el método run() directamente si ese es el comportamiento deseado, o (b) construir un nuevo subproceso con ese ejecutable y comenzar el subproceso .

Mejor aún, para obtener aún más desacoplamiento, revise la interfaz y el marco Executor en JDK 5 y posteriores. Esto le permite, en pocas palabras, desacoplar la ejecución de la tarea (la instancia Runnable) de cómo se ejecuta (la implementación Ejecutor, que podría ejecutar el Runnable en el Thread actual, en un Thread nuevo, usando un Thread existente de un grupo, y otras cosas).

9

Los métodos start() y run() separados en la clase Thread proporcionan dos formas de crear programas enhebrados. El método start() inicia la ejecución del nuevo hilo y llama al método run(). El método start() devuelve inmediatamente y el nuevo subproceso normalmente continúa hasta que devuelve el método run().

El método de la clase Thread 'run() no hace nada, por lo que las subclases deben anular el método con código para ejecutar en el segundo hilo. Si se crea una instancia de un subproceso con un argumento ejecutable, el método run() del subproceso ejecuta el método run() del objeto ejecutable en el nuevo subproceso.

Dependiendo de la naturaleza de su programa de roscado, llamando al método de rosca run() directamente puede dar el mismo resultado que llama a través del método start(), pero en este último caso, el código se ejecuta realmente en un nuevo hilo.

reference

+0

¡¡Igual que la respuesta de Tomalak !! Si ha hecho referencia desde algún lugar, por favor mencione eso !! – Barry

+0

'El método start() devuelve inmediatamente y el nuevo hilo normalmente continúa hasta que el returns.' método run() Si es' 'start() vuelve inmediatamente cómo es que el' run() 'continúa funcionando dado que se llamaba a sí mismo a partir 'start()' – KNU

7

Si la pregunta era - "¿por qué el método de inicio de la rosca se llama en lugar de directamente método run" entonces he contestado con un código de ejemplo a continuación. Espero que eso aclare. en el ejemplo siguiente:

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

    } 
} 
23

Ejecución thread.run() no crea un nuevo Thread en el que el código se ejecuta. Simplemente ejecuta el código en el subproceso actual desde el que se invoca el código thread.run().

Ejecutando thread.start() crea un nuevo subproceso de nivel de sistema operativo en el que se llama al método run().

En esencia:

único subproceso de programación → directamente llamando al run() método

multiproceso de programación → Al llamar al método start()

Además, como otros de ha mencionado , la 'prueba' parece ser el único caso aconsejable en el que puede invocar run() directamente desde su código.

+0

gracias, explicación muy clara y concisa – BustedSanta

2

Sólo una nota para los grandes comentarios anteriores: a veces su escritura un código multi-hilo que utiliza "start" método para ejecutar diferentes hilos. Usted encontrará que es mucho más fácil si se utiliza "run" (en lugar de "iniciar) para la depuración, ya que hace que el código se ejecute de forma sincrónica y depuración mucho más fácil.

-1
public class TestClass implements Runnable { 
    public static void main(String[] args) { 
     TestClass tc = new TestClass(); 

     Thread t1 = new Thread(tc); 
     System.out.println("Before Starting Thread " + Thread.currentThread().hashCode()); 
     t1.start(); 
     System.out.println("After Starting Thread " + Thread.currentThread().hashCode()); 
    } 

    @Override 
    public void run() { 
     System.out.println("TestClass Run method is Running with thread " + Thread.currentThread().hashCode());   
    } 
} 
+0

Hola Frnz, hora de salida y ejecutar el ejemplo anterior para entender con claridad la primera carrera con t1.start() y ver código hash y la próxima vez con t1.run() y hashcodes chk –

+0

¿Dónde está tu pregunta? –

Cuestiones relacionadas