2009-11-02 13 views
25

Ho il seguente problema e vorrei sapere cosa succede esattamente. Sto usando Java ScheduledExecutorService per eseguire un'attività ogni cinque minuti. Funziona molto bene. Gli esecutori hanno completamente cambiato il modo in cui eseguo la programmazione dei thread in Java.Eccezioni non gestite con gli esecutori pianificati Java

Ora, ho sfogliato Java Doc per informazioni su quale sarebbe il comportamento nel caso in cui l'operazione pianificata abbia esito negativo con un'eccezione non gestita, ma non è stato possibile trovare nulla.

La prossima operazione pianificata è ancora in esecuzione? Se c'è un'eccezione non gestita, l'esecutore pianificato interrompe l'attività di pianificazione? Qualcuno può indicare informazioni su questo semplice problema?

Grazie mille.

risposta

24

Il Javadoc di entrambi scheduleAtFixedRate e scheduleWithFixedDelay dice "Se qualsiasi esecuzione dell'attività rileva un'eccezione, le esecuzioni successive vengono eliminate." Non trovo che sia esattamente cristallino, ma sembra che stia dicendo che se il tuo metodo run genera un qualsiasi tipo di eccezione, allora lo schedulatore abbandonerà effettivamente quell'attività. Qualsiasi altra attività in esecuzione tramite tale scheduler non dovrebbe essere influenzata. Non dovrebbe essere difficile testare ciò che effettivamente fa ...

L'annullamento dell'attività potrebbe non essere necessariamente una cosa negativa. Se il metodo run lancia un RuntimeException, probabilmente ha un bug da qualche parte e lo stato del sistema è sconosciuto. Ma almeno consiglierei di prendere lo RuntimeException nel metodo di esecuzione e di registrare l'intera traccia dello stack su SEVERE. Puoi decidere di rethrow per annullare l'operazione, a seconda delle circostanze. Ma in entrambi i casi avrete bisogno del logging per avere una possibilità di combattere su cosa è andato storto.

+0

Grazie mille per la risposta. Non l'ho visto in API Doc. –

+5

Una rapida ricerca dell'origine per ThreadPoolExecutor (in cui è implementato STPE) suggerisce che RuntimeExceptions verrà catturato in modo ordinato e riportato indietro tramite ScheduledFuture, ma che causerà anche la chiusura del thread di lavoro. Il TPE noterà questa terminazione del thread di lavoro e produrrà una nuova sostituzione, se necessario. Vedere runWorker() e processWorkerExit() in java.util.concurrent.ThreadPoolExecutor nei sorgenti JDK o sul sito di Doug Lea. – andersoj

11

Se si utilizza o scheduleAtFixedDelay() e l'attività viene annullata con un'eccezione, tale attività non sarà riprogrammata. Tuttavia, altre attività indipendenti dovrebbero continuare ad essere eseguite come previsto. (Vedi API Docs). Se ti interessa che questo sia successo, puoi afferrare lo ScheduledFuture che viene restituito e chiamare il metodo get(). Se l'attività sottostante lancia un'eccezione, la espellerai dal metodo get(), racchiusa in un ExecutionException.

+0

Grazie mille per la risposta. +1. Peccato che non possa accettare due risposte come "la risposta". Grazie ancora. –

+0

Ehi, amico, Lachlan mi ha battuto sul pugno ... le regole sono regole. ;-) – andersoj

+0

Strano ... anche il mio compito successivo si ferma. –

-3

Sembra che l'API non definisca alcun meccanismo specifico di gestione delle eccezioni. Cioè l'eccezione non rilevata si apre solo attraverso i frame del thread e alla fine viene registrata su stderr.

vedo che è possibile sfruttare le seguenti strategie di gestione delle eccezioni:

+0

Non penso che queste eccezioni siano registrate. –

1

Questo uomo ha avuto lo stesso problema.

http://code.nomad-labs.com/2011/12/09/mother-fk-the-scheduledexecutorservice/

La sua soluzione è quello di catturare Exception all'interno del eseguibile e ri gettare un RuntimeException:

try { 
     theRunnable.run(); 
    } catch (Exception e) { 
     // LOG IT HERE!!! 
     System.err.println("error in executing: " + theRunnable + ". It will no longer be run!"); 
     e.printStackTrace(); 

     // and re throw it so that the Executor also gets this error so that it can do what it would 
     // usually do 
     throw new RuntimeException(e); 
} 
Problemi correlati