2009-09-21 41 views
95

Encontré preguntas similares hechas aquí pero no hubo respuestas para mi satisfacción. Volviendo a formular la pregunta nuevamente:Timer & TimerTask versus Thread + sleep en Java

Tengo una tarea que debe realizarse periódicamente (por ejemplo, intervalos de 1 minuto). ¿Cuál es la ventaja de utilizar Timertask & Timer para hacer esto en lugar de crear un nuevo hilo que tiene un ciclo infinito con sleep?

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 sueño-

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

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

Sírvanse comentar esta ..

Gracias,
-Keshav

Actualización:
Recientemente he encontrado otra diferencia entre el uso del temporizador frente Thread.sleep(). Supongamos que la hora actual del sistema es 11:00 a.m. Si restituimos la hora del sistema a 10:00 a.m. por algún motivo, The Timer DEJARÁ de ejecutar la tarea hasta que haya llegado a las 11:00 AM, mientras que el método Thread.sleep() continuará ejecutando la tarea sin obstáculos. Este puede ser un importante tomador de decisiones al decidir qué usar entre estos dos.

+21

Punto de orden: Timer y TimerTask están obsoletos, y han sido reemplazados por ExecutorService, aunque su punto sigue en pie. – skaffman

+0

Gracias por el consejo, decidí utilizar ExecutorService :) – Keshav

+0

Gracias a todos por las respuestas, seguramente me dio más comprensión! – Keshav

Respuesta

63

La ventaja de TimerTask es que expresa su intención mucho mejor (es decir, la legibilidad del código), y ya tiene la característica de cancelar() implementada.

en cuenta que puede ser escrito de 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); 
+0

si el temporizador se usa para Todos los días, en 2 horas específicas 9pm y 9am, ... ¿cómo dar los valores? en el código de arriba ... @Zed? – gumuruh

11

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 funciona mejor con problemas de subprocesamiento múltiple (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.

+0

Ese es un muy buen punto, gracias. – Ridcully

3

Hay un argumento crucial en contra de la administración de esta tarea mediante el uso de subprocesos Java y el método sleep. Está utilizando while(true) para permanecer indefinidamente en el ciclo e hibernar el hilo poniéndose a dormir. ¿Qué ocurre si NewUploadServer.getInstance().checkAndUploadFiles(); utiliza algunos recursos sincronizados? Otros hilos no podrán acceder a estos recursos, puede pasar hambre, lo que puede ralentizar toda su aplicación. Este tipo de errores son difíciles de diagnosticar y es una buena idea 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 de run() su TimerTask mientras deja que otros hilos que utilizan los recursos en el ínterin.

+16

No entiendo este argumento. Ambas opciones inician el mismo método desde un subproceso, ambas opciones están durmiendo en un subproceso mientras esperan su ejecución. No habrá diferencias de hambre entre las dos opciones. – satur9nine

4

No sé por qué, pero un programa que estaba escribiendo usaba Timers y su tamaño de almacenamiento dinámico aumentaba constantemente, una vez que lo cambiaba a Problema de hilo/suspensión resuelto.

+6

El temporizador crea una cola de tareas que se actualiza continuamente. Cuando termine el temporizador, puede que no se recoja basura inmediatamente. Por lo tanto, la creación de más Temporizadores solo agrega más objetos al montón. Thread.sleep() solo pausa el hilo, por lo que la sobrecarga de memoria sería extremadamente baja. –

3

Si recibes una excepción y te matan, es un problema. Pero TimerTask se encargará de eso. Se ejecutará independientemente de la falla en la ejecución anterior.

1

Creo que entiendo su problema, estoy viendo algo muy similar. Tengo temporizadores 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. Pensaría que la recolección de basura se ejecutaría cuando un temporizador está en reposo, pero no lo veo y, según la documentación, no.

Creo que el desove de nuevos hilos completa y permite la recolección de basura.

Alguien por favor demuéstrame que estoy equivocado, volver a escribir lo que heredé va a ser un dolor.