2010-11-03 13 views
5

Como complemento de mi aplicación actual, necesito crear un hilo separado que periódicamente haga algún procesamientoHilos; Crear un hilo separado para hacer algo de manera periódica

He creado una nueva clase para hacer todo esto, y esta clase se cargará al inicio de mi aplicación.

Esto es lo que tengo hasta ahora:

public class PeriodicChecker extends Thread 
{ 
    static 
    { 
     Thread t = new Thread(new PeriodicChecker()); 
     while(true) 
     { 
      t.run(); 
      try 
      { 
       Thread.sleep(5000l); 
      } 
      catch (InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 

    /** 
    * Private constructor to prevent instantiation 
    */ 
    private PeriodicChecker() 
    { 

    } 

    @Override 
    public void run() 
    { 
     System.out.println("Thread is doing something"); 
     // Actual business logic here, that is repeated 
    } 

} 

Quiero hacer constructor privado para evitar que otras personas intenten crear una instancia de esta clase de forma accidental. ¿Cómo puedo conseguir esto?

Además, ¿hay algo malo en mi implementación de dichos requisitos? Solo estoy creando un hilo que se ejecutará y luego dormirá, ¿me he perdido algo obvio? No he trabajado con hilos antes de

+1

¿Iniciando un hilo en un bloque estático? :) – willcodejavaforfood

Respuesta

9

usted tiene algunos erros conceptuales en su código ... por ejemplo:

  • usted debe llamar a start() y no correr(), porque se está ejecutando el método secuencial y no simultáneamente.
  • Puede llamar a start() solo una vez, no una vez en cada iteración de bucle.Después de eso, el hilo está en estado TERMINADO, debe crear un hilo nuevo para ejecutarlo nuevamente
  • No debe crear el hilo en el bloque estático, es una mala práctica, y tal vez el hilo se está ejecutando antes de que usted lo desee correr.

Debe leer algunos ejemplos sobre el hilo, es un poco difícil de entender al principio, y puede tener efectos no deseados con mucha facilidad.

Aquí es un poco de ejemplo, que puede hacer algo similar a la que desea:

public class PeriodicChecker extends Thread 
{ 
    @Override 
    public void run() 
    { 
     while(true) { 
      System.out.println("Thread is doing something"); 
      Thread.sleep(5000); 
     } 
    } 

} 

public OtherClass { 
    public static void main(String args[]) { 
     Thread t = new PeriodicChecker(); 
     t.start(); 
    } 
} 

Si desea que ninguno puede crear un nuevo hilo, se puede crear un producto único, por lo que puede estar seguro de que ninguno está creando más hilos.

+0

Falta un "}" después del ciclo while :) – Keshav

+0

He reparado el corchete, gracias. – greuze

3

En primer lugar para responder a su pregunta específica, ya ha logrado su objetivo. Has declarado que tu constructor es privado, lo que significa que ninguna clase externa puede llamarlo como new PeriodicChecker().

Mirando a su código sin embargo, hay una serie de otros problemas:

En primer lugar, se crea una instancia de la clase dentro de su propio constructor estático. El propósito de un constructor estático es inicializar cualquier estado estático que su clase pueda tener, de lo que las instancias de su clase pueden depender. Al crear una instancia de la clase dentro de el constructor estático, todas estas garantías salen por la ventana.

En segundo lugar, no creo que su subproceso se comporte de la manera en que espera que se comporte, principalmente porque en realidad no inicia otro subproceso :). Si tiene la intención de iniciar un nuevo hilo, debe llamar al método start() en ese objeto de hilo. Llamar al run() como lo hace no crea un nuevo hilo, simplemente ejecuta el método run() en el hilo actual.

Hoy en día, cuando desee crear un nuevo hilo para hacer algo, la forma recomendada de lograr esto es no ampliar Thread, sino implementar la interfaz Runnable. Esto le permite desacoplar el mecanismo del hilo, del comportamiento que pretende ejecutar.

Sobre la base de sus necesidades, sugeriría la supresión de una clase de nivel superior como éste, y en su lugar crear ya sea una clase interna privada en su aplicación de código de puesta en marcha, o incluso ir a una clase interna anónima:

public class Main { 

    public static void main(String[] args) { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       while(true) { 
        System.out.println("Thread is doing something"); 
        Thread.sleep(5000); 
       } 
      } 
     }).start(); 
    } 

} 
2

Es casi nunca derecho a extender Thread. Si alguna vez te encuentras haciendo esto, da un paso atrás, echa un vistazo y pregúntate si realmente necesitas cambiar la forma en que funciona la clase Thread.

Casi todos ocurrencias en las que veo extends Thread el trabajo se realiza mejor implementación de la interfaz Runnable o el uso de algún tipo de Timer.

12

Java ofrece ScheduledExecutorService para programar y ejecutar tareas o tareas periódicas con retraso. Debe proporcionar todas las características que necesita. Timer es otra clase que ofrece funcionalidades similares, pero yo recomendaría el ScheduledExecutorService over Timer por su flexibilidad de configuración y una mejor gestión de errores.

Cuestiones relacionadas