Pregunta

He encontrado preguntas similares hechas aquí pero no había respuestas a mi satisfacción. Así que reformular la pregunta de nuevo -

Tengo una tarea que hay que hacer sobre una base periódica (digamos intervalos de 1 minuto). ¿Qué es la ventaja de usar TimerTask y contador de tiempo para hacer esto en lugar de crear un nuevo hilo que tiene un bucle infinito con el sueño?

Fragmento de código usando TimerTask -

TimerTask uploadCheckerTimerTask = new TimerTask(){

 public void run() {
  NewUploadServer.getInstance().checkAndUploadFiles();
 }
};

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(uploadCheckerTimerTask, 0, 60 * 1000);

Fragmento de código usando hilo y dormir -

Thread t = new Thread(){
 public void run() {
  while(true) {
   NewUploadServer.getInstance().checkAndUploadFiles();
   Thread.sleep(60 * 1000);
  }
 }
};
t.start();

Realmente no tiene que preocuparse si me olvido de ciertos ciclos si la ejecución de la lógica necesita más que el intervalo de tiempo.

Por favor, comentar en este ..

Actualización:
Recientemente me encontré con otra diferencia entre el uso del temporizador frente Thread.sleep (). Supongamos que la hora actual del sistema es a las 11:00 PM. Si nos Rollback la hora del sistema s 10:00 AM por alguna razón, el disparador automático deja de ejecutar la tarea hasta que haya alcanzado las 11:00 horas, mientras que el método Thread.sleep () continuará la ejecución de la tarea sin obstáculos. Esto puede ser un tomador de decisiones importante en decidir qué usar entre estos dos.

¿Fue útil?

Solución

La ventaja de TimerTask es que expresa su intención mucho mejor (es decir, la legibilidad del código), y ya tiene la función de cancelación () implementado.

Tenga en cuenta que puede escribirse en una forma más corta, así como su propio ejemplo:

Timer uploadCheckerTimer = new Timer(true);
uploadCheckerTimer.scheduleAtFixedRate(
    new TimerTask() {
      public void run() { NewUploadServer.getInstance().checkAndUploadFiles(); }
    }, 0, 60 * 1000);

Otros consejos

Temporizador / TimerTask también tiene en cuenta el tiempo de ejecución de la tarea, por lo que será un poco más preciso. Y se trata mejor con problemas de multiproceso (tales como evitar los puntos muertos, etc.). Y, por supuesto, por lo general es mejor utilizar el código estándar bien probado en lugar de alguna solución casera.

No sé por qué, pero un programa que estaba escribiendo estaba usando temporizadores y es tamaño de la pila estaba aumentando constantemente, una vez que lo cambié a Tema / problema del sueño resuelto.

Si hace pasar llegar excepción y muere, eso es un problema. Pero TimerTask se hará cargo de ella. Se ejecutará independientemente de fracaso en la ejecución anterior.

Hay un argumento decisivo contra la gestión de esta tarea utilizando las hebras Java y método sleep. Está utilizando while(true) permanecer indefinidamente en el bucle y de hibernación el hilo poniendo a dormir. ¿Qué pasa si NewUploadServer.getInstance().checkAndUploadFiles(); retoma algunos recursos sincronizados. Otros temas serán incapaces de acceder a estos recursos, el hambre puede ocurrir que puede ralentizar toda su aplicación. Este tipo de errores son difíciles de diagnosticar y es una buena idea para evitar su existencia.

El otro abordaje desencadena la ejecución del código que le importa, es decir NewUploadServer.getInstance().checkAndUploadFiles(); llamando al método run() de su TimerTask mientras deja que otros hilos que utilizan los recursos en el ínterin.

Desde el Timer documentación :

  

Java 5.0 introduce el paquete java.util.concurrent y una de las   utilidades de concurrencia en el mismo es el que ScheduledThreadPoolExecutor   es un grupo de subprocesos para ejecutar tareas en repetidas ocasiones a un ritmo determinado o   retrasar. En efecto, es un sustituto más versátil para el   Temporizador / combinación TimerTask, ya que permite múltiples hilos de servicio,   Admisión de distintas unidades de tiempo, y no requiere TimerTask subclases   (Acaba de poner en práctica Ejecutable). Configuración ScheduledThreadPoolExecutor   con un hilo hace que sea equivalente a Timer.

Así Prefiero ScheduledThreadExecutor en lugar de Timer:

  • Timer utiliza hilo de fondo único que se utiliza para ejecutar todas las tareas del temporizador, secuencialmente. Lo que las tareas deben completar rápidamente de lo contrario se retrasará la ejecución de las tareas posteriores. Pero en el caso de ScheduledThreadPoolExecutor podemos configurar cualquier número de hilos y también puede tener un control total, proporcionando ThreadFactory.
  • Timer puede ser sensible a reloj del sistema, ya que hace uso del método de Object.wait(long). Pero no es ScheduledThreadPoolExecutor.
  • excepciones de tiempo de ejecución tirado en TimerTask que matarán hilo en particular, haciendo así temporizador muertos en donde como podemos manejar eso en ScheduledThreadPoolExecutor de manera que las otras tareas que no se vean afectados.
  • Timer proporciona un método cancel dar por terminado el temporizador y descartar cualquier tareas programadas, sin embargo, no interfiere con la tarea que se está ejecutando y deje que se finalice. Pero si el temporizador está funcionando como hilo de utilidad, entonces, si cancelamos o no, se dará por terminada tan pronto como todos los subprocesos de usuario están terminado de ejecutarse.

Temporizador vs Thread.sleep

Timer hace uso de Object.wait y es diferente de Thread.sleep

  1. A de espera (wait) hilo puede ser notificado (usando notify) por otro hilo, pero una de dormir no se puede ser, sólo puede ser interrumpido.
  2. Una espera (y notificar a) deben ocurrir en un bloque sincronizado en el objeto de monitor mientras que el sueño no lo hace.
  3. Mientras se está dormido no libera el bloqueo, se espera liberar el bloqueo para la espera objeto está llamada.

Creo que entiendo su problema, estoy viendo algo muy similar. Tengo temporizadores que son recurrentes, algunos cada 30 minutos y un poco de cada par de días. Por lo que leo y los comentarios que veo, parece que la recolección de basura nunca se quedará porque toda la tarea nunca es completa. Me gustaría pensar que la recolección de basura sería ejecutado cuando un temporizador está en reposo, pero no estoy de verlo y de acuerdo a la documentación no lo hace.

Creo que el desove nuevos temas completa y permitir la recolección de basura.

Alguien por favor demostrar lo contrario, volver a escribir lo que he heredado va a ser un dolor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top