Encontré preguntas similares hechas aquí, pero no hubo respuestas a mi satisfacción. Así que reformulando la pregunta de nuevo
Tengo una tarea que debe realizarse de forma periódica (por ejemplo, intervalos de 1 minuto). ¿Cuál es la ventaja de usar Timertask & Timer 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 Thread y sleep-
Thread t = new Thread(){
public void run() {
while(true) {
NewUploadServer.getInstance().checkAndUploadFiles();
Thread.sleep(60 * 1000);
}
}
};
t.start();
Realmente no tengo que preocuparme si pierdo ciertos ciclos si la ejecución de la lógica toma más tiempo que el intervalo.
Por favor comente sobre esto ...
Actualización:
Recientemente encontré otra diferencia entre usar Timer versus Thread.sleep (). Suponga que la hora actual del sistema es las 11:00 a. M. Si revertimos la hora del sistema a las 10:00 a. M. Por alguna razón, el temporizador DEJARÁ de ejecutar la tarea hasta que llegue a las 11:00 a. M., Mientras que el método Thread.sleep () continuará ejecutando la tarea sin obstáculos. Este puede ser un factor importante a la hora de decidir qué utilizar entre estos dos.
Respuestas:
La ventaja de TimerTask es que expresa su intención mucho mejor (es decir, legibilidad del código) y ya tiene implementada la función cancel ().
Tenga en cuenta que se puede escribir en una forma más corta, así como su propio ejemplo:
fuente
Timer / TimerTask también tiene en cuenta el tiempo de ejecución de su tarea, por lo que será un poco más preciso. Y se ocupa mejor de los problemas de subprocesos múltiples (como evitar interbloqueos, etc.). Y, por supuesto, generalmente es mejor usar un código estándar bien probado en lugar de una solución casera.
fuente
No sé por qué, pero un programa que estaba escribiendo usaba Timers y su tamaño de pila aumentaba constantemente, una vez que lo cambié a Thread / sleep problem resuelto.
fuente
Si obtiene una excepción y lo matan, eso es un problema. Pero TimerTask se encargará de ello. Se ejecutará independientemente de la falla en la ejecución anterior.
fuente
De la
Timer
documentación :Así que prefiero en
ScheduledThreadExecutor
lugar deTimer
:Timer
utiliza un único hilo de fondo que se utiliza para ejecutar todas las tareas del temporizador, de forma secuencial. Por lo tanto, las tareas deben completarse rápidamente, de lo contrario, retrasará la ejecución de las tareas posteriores. Pero en caso deScheduledThreadPoolExecutor
que podamos configurar cualquier número de subprocesos y también podemos tener el control total proporcionandoThreadFactory
.Timer
puede ser sensible al reloj del sistema, ya que utiliza elObject.wait(long)
método. PeroScheduledThreadPoolExecutor
no lo es.ScheduledThreadPoolExecutor
para que las otras tareas no se vean afectadas.Timer
proporciona uncancel
método para finalizar el temporizador y descartar cualquier tarea programada, sin embargo, no interfiere con la tarea que se está ejecutando actualmente y deja que finalice. Pero si el temporizador se está ejecutando como un hilo de demonio, lo cancelemos o no, terminará tan pronto como todos los hilos del usuario terminen de ejecutarse.Temporizador vs Thread.sleep
El temporizador hace uso
Object.wait
y es diferente deThread.sleep
wait
hilo en espera ( ) puede ser notificado (usandonotify
) por otro hilo, pero uno en espera no puede serlo, solo puede ser interrumpido.fuente
Hay un argumento crucial en contra de la gestión de esta tarea mediante hilos y
sleep
métodos de Java . Estás usandowhile(true)
permanecer indefinidamente en el bucle e hibernar el hilo poniéndolo a dormir. ¿Qué pasa siNewUploadServer.getInstance().checkAndUploadFiles();
ocupa algunos recursos sincronizados? Otros subprocesos no podrán acceder a estos recursos, puede ocurrir una inanición que puede ralentizar toda la aplicación. Este tipo de errores son difíciles de diagnosticar y es una buena idea evitar su existencia.El otro enfoque desencadena la ejecución del código que le importa, es decir,
NewUploadServer.getInstance().checkAndUploadFiles();
llamando alrun()
método de suTimerTask
mientras deja que otros hilos utilicen los recursos mientras tanto.fuente
Creo que entiendo tu problema, estoy viendo algo muy similar. Tengo temporizadores que son recurrentes, algunos cada 30 minutos y otros cada dos días. Por lo que leí y los comentarios que veo, parece que la recolección de basura nunca se ejecutará porque todas las tareas nunca se completan. Creo que la recolección de basura se ejecutaría cuando un temporizador está en suspensión, pero no lo veo y, según la documentación, no.
Creo que la generación de nuevos hilos se completa y permite la recolección de basura.
Alguien, por favor, demuestre que estoy equivocado, reescribir lo que heredé será un dolor.
fuente