2012-03-08 19 views
55

Tengo el siguiente fragmento de código:Cómo iniciar la clase de hilo anónimo

public class A { 
    public static void main(String[] arg) { 
     new Thread() { 
      public void run() { 
       System.out.println("blah"); 
      } 
     }; 
    } 
} 

En este caso, ¿cómo llamar al método start() para el hilo sin crear una instancia de la clase hilo?

+2

Java sigue [principio de sustitución liskov] (http://en.wikipedia.org/wiki/Liskov_substitution_principle), por lo que la instancia de la clase anónima que ha creado es ** también ** una instancia de 'Thread'. – Pacerier

Respuesta

127

Ya estás creando una instancia de la clase Thread; simplemente no estás haciendo nada con ella. Usted podría llamada start() sin necesidad de utilizar una variable local:

new Thread() 
{ 
    public void run() { 
     System.out.println("blah"); 
    } 
}.start(); 

... pero personalmente me gustaría normalmente asignarlo a una variable local, hacer cualquier otra cosa que desee (por ejemplo, la configuración del nombre, etc.) y luego iniciarlo:

Thread t = new Thread() { 
    public void run() { 
     System.out.println("blah"); 
    } 
}; 
t.start(); 
+2

Cuál es la diferencia entre la anterior y la creación de un ejecutor dentro del constructor de temas Nuevo tema (nueva Ejecutable() {public void run() {}} ); – Malwaregeek

+2

@Malwaregeek: Bueno, en un caso, la implementación es una subclase de 'Thread', y en otro caso hay una implementación de clase anónima de' Runnable'. Son diferentes, pero la diferencia generalmente sería irrelevante. –

+0

@Malwaregeek Aunque puede haber una ligera preferencia para implementar la interfaz 'Runnable'. [Vea la propia respuesta de Jon aquí] (https://stackoverflow.com/questions/541487/implements-runnable-vs-extends-thread). –

6

No exactamente seguro de que esto es lo que están pidiendo, pero se puede hacer algo como:

new Thread() { 
    public void run() { 
     System.out.println("blah"); 
    } 
}.start(); 

N otice el método start() al final de la clase anónima. Usted crea el objeto de subproceso pero necesita iniciarlo para obtener otro subproceso en ejecución.

mejor que crear una clase anónima Thread es crear una clase anónima Runnable:

new Thread(new Runnable() { 
    public void run() { 
     System.out.println("blah"); 
    } 
}).start(); 

lugar reemplazando el método run() en el Thread se inyecta un objetivo Runnable ser dirigido por el nuevo hilo. Este es un mejor patrón.

3

Sólo tiene que llamar inicio()

new Thread() 
{ 
    public void run() { 
     System.out.println("blah"); 
    } 
}.start(); 
3

Todo el new expresión es una referencia de objeto, por lo que los métodos se pueden invocar en él:

public class A { 
    public static void main(String[] arg) 
    { 
     new Thread() 
     { 
      public void run() { 
       System.out.println("blah"); 
      } 
     }.start(); 
    } 
} 
13

Desde las clases anónimas extienden la clase dada se puede almacenar ellos en una variable.

por ejemplo.

Thread t = new Thread() 
{ 
    public void run() { 
     System.out.println("blah"); 
    } 
}; 
t.start(); 

Como alternativa, puede simplemente llamar al método de inicio en el objeto que ha creado inmediatamente.

new Thread() 
{ 
    public void run() { 
     System.out.println("blah"); 
    } 
}.start(); 
// similar to new Thread().start(); 

Aunque personalmente, siempre me aconsejaría la creación de una instancia anónima de Ejecutable en lugar de hilo como el compilador le advertirá si accidentalmente obtiene el método de firma incorrecta (para una clase anónima se le advertirá de todos modos pienso, ya que las clases anónimas no pueden definir nuevos métodos no privados).

por ejemplo

new Thread(new Runnable() 
{ 
    @Override 
    public void run() { 
     System.out.println("blah"); 
    } 
}).start(); 
+0

También puede usar una [expresión lambda] (https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html): 'new Thread (() -> System.out.println (" blah "))'. –

0

Añadir: ahora se puede utilizar lambda para simplificar su sintaxis.

public class A { 
    public static void main(String[] arg) 
    { 
     Thread th = new Thread(() -> {System.out.println("blah");}); 
     th.start(); 
    } 
} 
0

Me sorprende que no haya visto ninguna mención del marco Executor de Java para las respuestas de esta pregunta.Uno de los principales puntos de venta del marco Executor es que no tiene que lidiar con subprocesos de bajo nivel. En cambio, se trata del nivel más alto de abstracción de ExecutorService s. Entonces, en lugar de iniciar manualmente un hilo, simplemente ejecuta el ejecutor que envuelve Runnable. Con el ejecutor de subprocesos único, la instancia Runnable que crea se envolverá internamente y se ejecutará como un subproceso.

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
// ... 

ExecutorService threadExecutor = Executors.newSingleThreadExecutor(); 
try { 
    threadExecutor.execute(
    new Runnable() { 
     @Override 
     public void run() { 
     System.out.println("blah"); 
     } 
    } 
); 
} finally { 
    threadExecutor.shutdownNow(); 
} 

Para mayor comodidad, vea el code on JDoodle.

Cuestiones relacionadas