2013-01-10 10 views
5

Io uso ScheduledExecutorService.scheduleAtFixedRate di eseguire un compito quotidiano, in questo modo:Precisione della ScheduledExecutorService su OS normale/JVM

executor.scheduleAtFixedRate(task, d, 24L * 3600 * 1000, TimeUnit.MILLISECONDS); 

(d è il ritardo iniziale in millisecondi).

L'executor viene creato da Executors.newSingleThreadScheduledExecutor() ed esegue più attività, ma sono tutte pianificate a poche ore di distanza e richiedono al massimo alcuni minuti.

So che ScheduledExecutorService non garantisce l'accuratezza e mi piacerebbe avere un sistema operativo in tempo reale e JVM per ottenerlo. Questo non è un requisito per il mio compito, però.

Ho notato che su un server Windows 2003, utilizzando JDK 1.7.0_03, l'attività scorre di quasi 10 secondi al giorno. Questo rende circa 5 minuti al mese, che è accettabile per la mia applicazione. Probabilmente dovrò implementare nuovamente la riprogrammazione, perché voglio che l'attività venga eseguita in un momento locale specifico, quindi dovrò occuparmi personalmente di DST. Il servizio funziona per lunghi periodi di tempo - un anno e mezzo senza riavvio non è così insolito.

Tuttavia, penso che un'accuratezza di 10 secondi al giorno sia piuttosto alta per un sistema quasi inattivo, e mi chiedo se dovrei essere preparato a comportamenti ancora peggiori.

Quindi la mia domanda riguarda le tue esperienze con scheduleAtFixedRate. I 10 secondi/giorno sono normali? Otterrò una precisione migliore o peggiore in altri ambienti (i nostri clienti usano anche server Linux e Solaris)? O i 10 secondi sono un'indicazione che qualcosa non va nel nostro ambiente?

+1

Nota: '24L * 3600 * 1000, TimeUnit.MILLISECONDS' equivale a' 1, TimeUnit.DAYS' ... Questo è l'intero punto di timeunits: evitare le conversioni dell'unità di tempo! – assylias

+1

@assylias yes, ma initialDelay d è in millisecondi e c'è solo un argomento TimeUnit. – Chris

+1

Avvio su un'ora locale specifica utilizzando Quartz o Spring 'task: scheduled-tasks', quindi non si ha questo problema. – luukes

risposta

2

Per un'attività di lunga durata, non è troppo sorprendente. Un altro problema è che utilizza nanoTime() che non è sincronizzato con NTP o simili. Ciò può risultare in deriva con l'orologio da parete.

Un modo per evitare ciò è pianificare più volte come suggerito. I compiti ripetitivi in ​​realtà riprogrammano se stessi (motivo per cui non possono generare eccezioni, vedi di seguito). È possibile avere un'attività one shot che riprogrammandosi alla fine, utilizzando l'ora dell'orologio a muro e tenendo conto dei risparmi dell'elenco giornaliero.

BTW: Vorrei essere sicuro di notare eccezioni o addirittura lanciare Throwable. Se non lo fai, il tuo compito si fermerà, forse in silenzio (a meno che tu non stia guardando l'oggetto Future restituito)

Quello che faccio è imbrogliare un po '. Ho un compito che si sveglia ogni 1 - 10 secondi e controlla se è necessario eseguire e se non restituisce. Il sovraccarico di solito è banale se non si hanno migliaia di compiti ed è molto più semplice da implementare.

Problemi correlati