Détectez si l'heure système a été déplacée vers l'arrière en java ou si les temporisateurs de preuve temporelle


J'ai une boîte qui utilise ntp et nous avons plusieurs programmes java en cours d'exécution sur eux qui affichent une horloge. Le problème que nous rencontrons est que si quelque chose déclenche l'heure système en arrière tous nos minuteries qui font des choses comme animer l'arrêt de l'horloge et attendre que l'heure système reprenne où elle était. J'ai besoin de trouver un moyen de détecter quand l'heure du système a été modifiée en arrière et de réinitialiser tous nos minuteries ou un ensemble de minuteries qui peuvent planifier à plusieurs reprises mais toujours être une preuve contre le horloge en train de changer.

En guise de note, j'ai déjà essayé le package quartz timer, il a le même problème que les minuteries java régulières.

Author: tharris, 2010-08-12

2 answers

À peu près tous les minuteries définissent une heure future, puis comparent régulièrement l'heure actuelle à l'heure donnée. C'est pourquoi les minuteries "décrochent" lorsque le temps réel recule.

Malheureusement, TOUS les minuteries de la JVM sont liées à l'heure de la journée. Par exemple, java.util.Timer fait un objet.attendez (millisecondes) qu'un événement se déclenche. Cela se résume à un appel de thread qui fait également une attente, pendant t millisecondes. Et c'est toujours relatif à "l'heure de la journée".

Donc, fondamentalement, il n'y a pas de réel façon de le faire en java sans rotation, boucle de succion du PROCESSEUR attendant le temps de revenir en arrière afin d'informer les minuteries que vous souhaitez réinitialiser.

 5
Author: Will Hartung, 2010-08-12 17:36:48

On dirait que le widget horloge est ce qui est cassé. Un widget d'interface utilisateur doit afficher l'état actuel du modèle, où le modèle, dans ce cas, est l'heure système. Bien sûr, pour une horloge, vous devez planifier un repaint() toutes les secondes, mais lorsque la peinture se produit, elle devrait rendre l'heure système, pas essayer de garder une trace de l'heure elle-même.

Ce principe s'appliquerait même aux composants non-UI. Déterminez la tolérance du composant aux erreurs de synchronisation et disposez d'un thread d'arrière-plan qui actualise le composant à cet intervalle. Lors d'une actualisation, cependant, l'heure système est utilisée, pas une horloge interne indépendante.


Mise à Jour:

Le ScheduledExecutorService de base ne souffre pas de ce problème, du moins sur ma plate-forme.

ScheduledExecutorService worker = Executors.newScheduledThreadPool(1);
worker.schedule(new Runnable() {
  public void run()
  {
    update();
  }
}, 100, TimeUnit.MILLISECONDS);
 1
Author: erickson, 2010-08-18 07:54:49