2009-09-21 18 views
95

Ho trovato domande simili qui ma non ci sono state risposte alla mia soddisfazione. Quindi riformulare nuovamente la domanda:Timer e TimerTask contro Thread + sleep in Java

Ho un'attività che deve essere eseguita su base periodica (ad esempio intervalli di 1 minuto). Qual è il vantaggio di utilizzare Timer tempTimer per farlo invece di creare un nuovo thread che ha un ciclo infinito con sleep?

Snippet di codice utilizzando timertask-

TimerTask uploadCheckerTimerTask = new TimerTask(){ 

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

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

frammento di codice con filo e sonno-

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

io davvero non si deve preoccupare se manco certi cicli se l'esecuzione della logica prende più del tempo dell'intervallo.

Si prega di commentare questa ..

Grazie,
-Keshav

Aggiornamento:
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.

+21

Point of order: Timer e TimerTask sono obsoleti e sono stati effettivamente sostituiti da ExecutorService, sebbene il punto rimanga valido. – skaffman

+0

Grazie per il suggerimento, ho deciso di utilizzare ExecutorService :) – Keshav

+0

Grazie a tutti per le risposte, sicuramente mi ha dato più comprensione! – Keshav

risposta

63

Il vantaggio di TimerTask è che esprime molto meglio l'intenzione (ovvero la leggibilità del codice) e ha già implementato la funzione cancel().

Si noti che può essere scritto in una forma più breve così come il vostro esempio:

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

se il timer viene utilizzato per tutti i giorni, in 2 ore specifiche 9pm e 9am, ... come fornire i valori? nel codice sopra ... @Zed? – gumuruh

11

Timer/TimerTask prende in considerazione anche il tempo di esecuzione del vostro compito, quindi sarà un po 'più precisa . 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.

+0

Questo è un ottimo punto, grazie. – Ridcully

3

C'è un argomento cruciale contro la gestione di questa attività utilizzando i thread Java e il metodo sleep. Si sta utilizzando while(true) per rimanere indefinitamente nel ciclo e ibernare il thread mettendo in pausa. Cosa succede se NewUploadServer.getInstance().checkAndUploadFiles(); occupa 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 attiva l'esecuzione del codice che conta per voi, vale a dire NewUploadServer.getInstance().checkAndUploadFiles(); chiamando il metodo del run() tuo TimerTask mentre lasciando altri thread che utilizzano le risorse nel frattempo.

+16

Non capisco questo argomento. Entrambe le opzioni avviano lo stesso metodo da un thread, entrambe le opzioni stanno dormendo in un thread mentre aspettano di essere eseguite. Non ci saranno differenze di fame tra le due scelte. – satur9nine

4

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

+6

Il timer crea una coda di attività che viene continuamente aggiornata. Quando il timer è terminato, potrebbe non essere raccolto immediatamente. Quindi la creazione di più Timer aggiunge solo più oggetti all'heap. Thread.sleep() interrompe solo il thread, quindi l'overhead della memoria sarebbe estremamente basso. –

3

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.

1

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 si prega di dimostrare che ho torto, riscrivere ciò che ho ereditato sarà un dolore.