2012-10-07 1248 views
31

Quiero usar la clase anónima para ejecutable. Hay dos vías, pero no sé si lo hacen lo mismo o no:La mejor manera de crear y usar una clase Runnable anónima

Método uno: usando directamente Ejecutable y llamar a correr

new Runnable() { 
    @Override 
    public void run() { 
    } 
}.run(); 

Método dos: crear un ejecutable en el anonimato, y pegar para Enhebrar, utilizando el método de inicio en lugar de ejecutar:

new Thread(new Runnable() { 
    @Override 
    public void run() { 
    } 
}).start(); 

Creo que el método dos es muy cierto. Pero, no sé si hace lo mismo que el método uno. ¿Podemos llamar al método run en Runnable directamente?

Gracias :)

Respuesta

21

No, lo normal es que no llamar run() directamente en un Ejecutable como se puede obtener ningún fondo roscado de esa manera. Si no quiere y necesita un hilo de fondo, llame directamente al run() directamente, pero si quiere crear un hilo de fondo y ejecutar Runnable desde allí, debe crear un nuevo hilo y luego pasar el ejecutable a su constructor, y llame al start().

Además, hay otras formas de llevar a cabo esta tarea, incluido el uso de ejecutores y ejecutores, y debe considerar los usos de este, ya que ofrecen más flexibilidad y potencia que el uso de un objeto Thread.

También querrá echarle un vistazo al uso de la interfaz Future y la clase FutureTasks que son como Runnables, solo que le permiten devolver un resultado cuando se completa. Si usaste un SwingWorker, entonces ya has usado una interfaz Future sin darte cuenta.

1

La primera es incorrecta: no crea un nuevo hilo, por lo que es inútil.

Es como poner el código fuera de un ejecutable.

Tenga en cuenta que hay dos maneras de lanzamiento de un nuevo hilo en el código definido en una clase anónima, pero su método de as described in Thread's javadoc no está entre ellos y su método de es el más habitual debe preferir .

1

Como @Hovercraft menciona, si llama directamente a un método Runnable.run(), no se crea un Thread en absoluto. Es como llamar a cualquier otro método (System.out.println(...), ...).

Cuando se pasa un objeto Runnable a la Thread constructor, que establece el campo target en el Thread para que sea su objeto:

this.target = target; 

Luego, cuando se llama a start() en el Thread, esto hace el trabajo de que se bifurcan el nuevo hilo y llamando al método Thread.run().Los Thread.run() llamadas a métodos del objetivo run() a su vez:

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

Y pasando el Runnable a un Thread y luego llamar start() es la manera de ejecutar su Runnable en el fondo en un hilo separado.

6

Su método 1 no tiene sentido. La interfaz Runnable es significativa para enhebrar solo cuando se ejecuta dentro de un Thread (su método 2). Si usted quiere encontrar otra manera de envolver en línea, un trozo de código dentro de un hilo, esto podría ser una:

Thread t = new Thread() 
{ 
    public void run() 
    { 
     // put whatever code you want to run inside the thread here. 
    } 
}; 
t.start(); 
23

Como los otros han mencionado, el uso de la clase Thread es la forma correcta. Sin embargo, también debe consultar el uso del marco Javas Executors para gestionar los subprocesos en ejecución.

Executors.newSingleThreadExecutor().execute(new Runnable() { 
    @Override 
    public void run() { 
     // code in here 
    } 
}); 

Por supuesto, solo usar Thread directamente está bien. Pero generalmente se recomienda (o prefiere) usar el marco. Deje que Java maneje los detalles finos para usted.

+0

En este caso, ¿hay alguna manera de que pueda pasar un parámetro al método run()? – kenshinji

+0

@kenshinji no, no, tiene que pasar esos parámetros en el constructor de clase que implementa Runnable. –

4

Me gustaría agregar algo sobre esta discusión (ya recibiste buenas respuestas).
Si su objeto Runnable es sin estado, para reducir las asignaciones de memoria (que toman tiempo + consumen algo de memoria, piense en un caso en el que una aplicación usa hilos), considere tener un campo estático que contenga el objeto ejecutable.

private static Runnable runnable = new Runnable() { //Once again - do this only if this is a statelss object! 
    public void run() { 
    } 
} 

//Use the runnable somewhere in the code 
2

En el método uno se acaba de funcionar como un método como el interface Runnable implementación y llamándola, pero no habrá ningún fondo hilo creado. El hecho es que cuando llamamos al método de inicio provoca que el subproceso corrosponding comience a ejecutarse, la Máquina Virtual Java llama internamente al método de ejecución de este subproceso. Entonces, para comenzar un hilo, debemos llamar al método de inicio con la referencia Ejecución ejecutable. En el método uno, no podemos llamar al método de inicio con la referencia de la interfaz ejecutable ya que la interfaz ejecutable no admite el método start(). Por lo tanto, es obligatorio crear el objeto de la clase Thread para iniciar la ejecución de la secuencia.

0

Su método 1 por lo general no puede hacer ningún trabajo útil. Con este método, si desea obtener el resultado del programa HelloWorld.java simple, es decir, "Hello World", se parecerá al siguiente código inútil, pero imprime "Hello World". Entonces deberías usar tu Segundo Método. Código inútil:

class MyRunnable implements Runnable { 

    public void run() { 
    System.out.println("Hello World"); 
    } 

    public static void main(String[]arg){ 
    MyRunnable myRunnable = new NamedRunnable(); 
    namedRunnable.run(); 
    } 
} 
0

Recuerde siempre que Runnable es solo un código que desea o puede ejecutar en un subproceso. Una forma de definir Código Ejecutable anónima es:

Runnable codeToRunOnThread=new Runnable() { 
     @Override 
     public void run() { 
     //code to run in a thread you want 
     } 
    }; 

Y entonces usted puede crear un hilo y pasar el Ejecutable que ha creado para que el nuevo hilo como este

Thread myThread=new Thread(codeToRunOnThread); 
    myThread.start(); 

Después de llamar al método start() de la clase Thread, el código que va dentro del método run() se ejecuta en el hilo recién creado.

También puede buscar otra manera de crear objetos Ejecutable here

0

Aquí es un simple ejemplo de código de cómo crear una clase Ejecutable anónima y manejar adecuadamente pérdida de memoria (Ejemplo para Android):

public class MainActivity extends Activity{ 
@Override 
protected void onCreate(Bundle savedInstanceState) { 

      MyRunnable myRunnable = new MyRunnable(this); 
      myHandler.postDelayed(myRunnable, TimeUnits); 
} 

// Must be declared as a static class  
private static class MyRunnable implements Runnable { 
     WeakReference<MainActivity> mActivity; 
     // Creating weakreference 
     MyRunnable(MainActivity activity) { 
      mActivity = new WeakReference<>(activity); 
     } 

     @Override 
     public void run() { 
      MainActivity activity = mActivity.get(); 
      // Checking reference exist or not 
      if (activity != null) { 
        //Do necessary tasks 
       } 
      } 
     } 
    } 

} 
Cuestiones relacionadas