Timer e TimerTask contro Thread + sleep in Java

Ho trovato domande simili qui ma non ci sono state risposte alla mia soddisfazione. Quindi riformulando nuovamente la domanda-

Ho un compito che deve essere svolto su base periodica (ad esempio intervalli di 1 minuto). Qual è il vantaggio dell’uso di Timertask & Timer per fare ciò anziché creare un nuovo thread che ha un ciclo infinito con sleep?

Snippet di codice che utilizza il timestask-

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

Snippet di codice che utilizza Thread e sleep-

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

Non devo davvero preoccuparmi se mi mancano certi cicli se l’esecuzione della logica richiede più dell’intervallo di tempo.

Si prega di commentare questo ..

Grazie,
-Keshav

Aggiornare:
Recentemente ho trovato un’altra differenza tra l’utilizzo di Timer contro Thread.sleep (). Supponiamo che l’ora attuale del sistema sia 11:00 AM. Se per qualche motivo il rollback delle ore del sistema viene effettuato alle 10:00 AM, il timer smetterà di eseguire l’attività fino a quando non avrà raggiunto le 11:00 AM, mentre il metodo Thread.sleep () continuerà a eseguire l’attività senza impedimenti. Questo può essere un importante fattore decisionale nel decidere cosa usare tra questi due.

Il vantaggio di TimerTask è che esprime molto meglio le tue intenzioni (ad esempio la leggibilità del codice) e ha già implementato la funzione cancel ().

Si noti che può essere scritto in un formato più breve così come il proprio esempio:

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

Timer / TimerTask tiene anche conto del tempo di esecuzione del tuo compito, quindi sarà un po ‘più accurato. E si occupa meglio dei problemi di multithreading (come evitare deadlock, ecc.). E, naturalmente, di solito è meglio usare un codice standard ben testato anziché una soluzione fatta in casa.

Non so perché, ma un programma che stavo scrivendo stava usando Timer e la sua dimensione di heap aumentava costantemente, una volta che l’ho cambiato in Thread / sleep risolto.

C’è un argomento cruciale contro la gestione di questa attività utilizzando i thread Java e il metodo sleep . Stai usando while(true) per rimanere indefinitamente nel loop e mettilo in letargo mettendo in sospensione. Cosa succede se NewUploadServer.getInstance().checkAndUploadFiles(); prende alcune risorse sincronizzate. Gli altri thread non saranno in grado di accedere a queste risorse, potrebbe verificarsi l’inaridimento che può rallentare l’intera applicazione. Questi tipi di errori sono difficili da diagnosticare ed è una buona idea prevenirne l’esistenza.

L’altro aproach triggers l’esecuzione del codice che ti interessa, ovvero NewUploadServer.getInstance().checkAndUploadFiles(); chiamando il metodo run() del TimerTask mentre nel frattempo lascia che altri thread utilizzino le risorse.

Se il thread ottiene l’eccezione e viene ucciso, questo è un problema. Ma TimerTask si prenderà cura di esso. Verrà eseguito indipendentemente dall’errore nella corsa precedente.

Penso di aver capito il tuo problema, sto vedendo qualcosa di molto simile. Ho timer che sono ricorrenti, alcuni ogni 30 minuti e alcuni ogni due giorni. Da quello che ho letto e dai commenti che vedo, sembra che la garbage collection non verrà mai eseguita perché tutte le attività non sono mai complete. Penserei che la raccolta dei rifiuti verrebbe eseguita quando un timer è in stop, ma non lo vedo e, secondo la documentazione, non lo è.

Penso che la generazione di nuovi thread completi e consenta la garbage collection.

Qualcuno, per favore, dimostrami che ho torto, riscrivendo ciò che ho ereditato sarà un dolore.