2010-08-12 10 views
6

Ho una casella che utilizza ntp e su di essi sono presenti diversi programmi java che visualizzano un orologio. Il problema che stiamo affrontando è se il sistema avanza indietro nel tempo tutti i nostri timer che fanno cose come animare il cronometro e aspettare fino a che il tempo del sistema non ritorna a dove si trovava. Devo trovare un modo per rilevare quando l'ora del sistema è stata modificata all'indietro e ripristinare tutti i nostri timer o un set di timer che possono essere programmati più volte, ma sono comunque una prova contro il cambio dell'orologio.Rileva se il tempo di sistema è stato spostato indietro in java, o temporizzatori a prova di tempo

Come nota ho già provato il pacchetto del timer al quarzo che ha lo stesso problema dei normali timer java.

+0

Quanto è lontano l'orologio? ntp di solito usa l'orologio slew per spostare leggermente l'orologio in entrambe le direzioni e non dovrebbe aver bisogno di cambiarlo di un numero elevato di secondi. – Gray

+0

c'è qualche bug nel sistema che sta mandando il tempo indietro di 3 o 4 ore. Quasi come se avessimo 2 server NTP in competizione che non possono essere d'accordo. – tharris

risposta

5

Quasi tutti i timer impostano un orario futuro e quindi confrontano regolarmente l'ora corrente con il tempo specificato. Ecco perché i timer si "bloccano" quando il tempo reale procede all'indietro.

Sfortunatamente, TUTTI i timer della JVM sono correlati all'ora del giorno. Ad esempio, java.util.Timer esegue un Object.wait (milliSeconds) per l'attivazione di un evento. Questo si riduce a una chiamata thread che fa anche un'attesa, per millisecondi. Ed è sempre relativo al "momento del giorno".

Quindi, in pratica, non c'è un modo reale di farlo in java senza un ciclo di rotazione della CPU in attesa del tempo per tornare indietro per informare i timer che si desidera ripristinare.

+0

Sì, questo è anche ciò che mi è venuto in mente, tuttavia ho trovato che Thread.sleep() è immune all'ora di sistema modificata, quindi suppongo che potrei avere un thread che dorme per 1 poi controlla per vedere se il tempo è passato all'indietro. – tharris

1

Sembra che il widget dell'orologio sia ciò che è rotto. Un widget UI dovrebbe visualizzare lo stato corrente del modello, in cui il modello, in questo caso, è l'ora del sistema. Certo, per un orologio, dovresti programmare un repaint() ogni secondo, ma quando si verifica il repaint, dovrebbe rendere l'ora del sistema, non cercare di tenere traccia del tempo stesso.

Questo principio si applica anche ai componenti non UI. Determina la tolleranza del componente agli errori di temporizzazione e dispone di un thread in background che aggiorna il componente a quell'intervallo. Durante un aggiornamento, tuttavia, viene utilizzata l'ora del sistema, non un orologio interno indipendente.


Aggiornamento:

La base ScheduledExecutorService non soffre di questo problema, almeno sulla mia piattaforma.

+0

Il problema non è che il widgit sta cercando di tenere traccia del tempo stesso, chiama new Date() una volta al secondo, è che se si sposta indietro il tempo del sistema allora i timer java che effettivamente aggiornano/animano l'orologio sospendono la loro esecuzione fino a il sistema recupera fino a dove si trovava prima. – tharris

+0

@tharris - Vedo; Non avevo avuto questo problema prima. Tuttavia, l'implementazione 'ScheduledExecutorService' che utilizzo sembra essere immune al problema e ha un'API simile alla classe' Timer' (sebbene faccia parte del più recente e molto più robusto pacchetto 'java.util.concurrent'). Vedi il mio aggiornamento per un esempio. – erickson

+0

@erickson :(questo non funziona con ubuntu 11.10 java 6 update 26. Ora ho anche domande sullo stesso http://stackoverflow.com/questions/9044423/java-scheduler-which-is-completely-independent-of -sistemi temporali del sistema – YoK

Problemi correlati