Faire une minuterie simple en Java


Je n'arrive pas à comprendre comment faire une minuterie simple en java. Tout ce dont j'ai besoin, c'est d'afficher l'heure, vraiment. Donc, juste une méthode de début, et il continue à compter comme 0:00, 0:01, 0:02, etc. J'ai vu d'autres messages similaires sur le forum à ce sujet, mais tout le code est un peu compliqué pour mon niveau de compréhension; je suis un peu nouveau sur java. Mais il ne devrait pas être si difficile de faire une minuterie qui ne fait qu'effectuer une telle fonction de base? Si quelqu'un pouvait aider, ce serait grandement apprécié:)

Author: Peter Elliott, 2012-05-30

2 answers

Ce n'est pas difficile. Cependant, je vous préviens que j'ai vu des réponses très confuses sur stack overflow, dans certains cas des habitudes de codage choquantes, alors soyez très prudent. Permettez-moi d'abord de répondre à la question.

Si semble que la plus grande erreur que les programmeurs font dans la mise en œuvre d'une minuterie, est de penser qu'ils ont besoin de quelque chose pour garder une trace de l'heure actuelle. Autrement dit, ils écrivent une sorte de boucle qui incrémente une variable chaque seconde ou une chose aussi stupide. Vous n' pas besoin d'écrire du code pour garder une trace du temps. La fonction System.currentTimeMillis() le fera pour vous, et elle le fait assez précisément.

Le code de minuterie impliquera deux aspects que de nombreux programmeurs mélangent:

  1. calcul du temps
  2. rafraîchissement de l'affichage

Tout ce que vous devez faire pour calculer le temps d'affichage, est d'enregistrer le temps que la minuterie a commencé:

long startTime = System.currentTimeMillis();

Plus tard, lorsque vous souhaitez afficher la quantité de temps, vous soustrayez simplement cela de à l'heure actuelle.

long elapsedTime = System.currentTimeMillis() - startTime;
long elapsedSeconds = elapsedTime / 1000;
long secondsDisplay = elapsedSeconds % 60;
long elapsedMinutes = elapsedSeconds / 60;
//put here code to format and display the values

La plus grande erreur que font les programmeurs est de penser qu'ils ont besoin d'une variable pour contenir l'heure actuelle, puis d'écrire du code pour incrémenter cette variable chaque seconde, par exemple quelque chose appelé "elapsedSeconds" qu'ils maintiennent. Le problème est que vous pouvez planifier le code à appeler toutes les secondes, mais il n'y a aucune garantie de savoir exactement quand ce code sera appelé. Si le système est occupé, ce code peut être appelé un peu plus tard que le second. Si le système est extrêmement occupé (par exemple la récupération de page à partir d'un disque défectueux), il pourrait en fait être plusieurs secondes en retard. Code qui utilise le Thread.la fonction sleep (1000) pour boucler chaque seconde constatera que l'erreur s'accumule au fil du temps. Si sleep retourne 300 ms en retard une fois, cette erreur est aggravée dans votre calcul de l'heure. Tout cela est complètement inutile car le système d'exploitation a une fonction pour vous indiquer l'heure actuelle.

Le calcul ci-dessus sera précis si vous exécutez ce code toutes les secondes, 100 fois par seconde ou une fois toutes les 3,572 secondes. Le fait est que currentTimeMillis() est la représentation exacte de l'heure quel que soit le moment où ce code est appelé -- et c'est une considération importante car les événements thread et timer ne sont pas garantis pour être précis à un moment spécifique.

Le deuxième aspect d'une minuterie est l'actualisation de l'affichage. Cela dépendra de la technologie que vous utilisez pour afficher avec. Dans un environnement graphique vous devez planifier paint événement. Vous souhaitez que ces événements de peinture viennent juste après l'heure à laquelle l'affichage devrait changer. Cependant, il est délicat. Vous pouvez demander un événement paint, mais il peut y avoir des centaines d'autres événements paint en file d'attente pour être traités avant le vôtre.

Une façon paresseuse de le faire est de planifier 10 événements de peinture par seconde. Parce que le calcul du temps ne dépend pas du code appelé à un moment donné, et parce que peu importe si vous repeignez le écran avec le même temps, cette approche garantit plus ou moins que l'heure affichée affichera le bon moment dans environ 1/10 de seconde. Cela semble un peu un gaspillage, parce que 9 fois sur 10 vous peignez ce qui est déjà à l'écran.

Si vous écrivez un programme avec une animation quelconque (comme un jeu) qui rafraîchit l'écran 30 fois par seconde, alors vous n'avez rien à faire. Il suffit d'incorporer l'appel d'affichage de la minuterie dans votre rafraîchissement d'écran régulier.

Si les événements paint sont coûteux, ou si vous écrivez un programme qui effectue une sortie de type terminal, vous pouvez optimiser la planification des événements en calculant le temps restant jusqu'à ce que l'affichage change:

long elapsedTime = System.currentTimeMillis() - startTime;
long timeTillNextDisplayChange = 1000 - (elapsedTime % 1000);

La variable timeTillNextDisplayChange contient le nombre de millisecondes que vous devez attendre jusqu'à ce que la partie secondes de la minuterie change. Vous pouvez ensuite planifier un événement paint pour qu'il se produise à ce moment-là, en appelant éventuellement Thread.sleep(timeTillNextDisplayChange) et après la mise en veille, effectuez la sortie. Si votre code est en cours d'exécution dans un navigateur, vous pouvez utiliser cette technique pour mettre à jour la page DOM au bon moment.

Notez qu'il n'y a rien dans ce calcul de l'actualisation de l'affichage qui affecte la précision de la minuterie elle-même. Le thread peut revenir du sommeil 10 ms en retard, voire 500 ms en retard, et la précision de la minuterie ne sera pas effectuée. À chaque passage, nous calculons le temps d'attente à partir du currentTimeMillis, donc être appelé en retard à une occasion ne provoquera pas d'affichages ultérieurs fin.

C'est la clé d'une minuterie précise. Ne vous attendez pas à ce que le système d'exploitation appelle votre routine ou envoie l'événement paint exactement quand vous le demandez. Habituellement, bien sûr, avec les machines modernes, le système d'exploitation est remarquablement réactif et précis. Cela se produit dans des situations de test où vous n'exécutez pas grand-chose d'autre, et la minuterie semble fonctionner. Mais, en production, dans une situation de stress rare, vous ne voulez pas que votre minuterie "dérive" parce que le système est occupé.

 20
Author: AgilePro, 2013-01-14 17:22:17

Vous pouvez utiliser la classe Timer de java.util ou d'une autre manière, ce qui est plus compliqué, est avec des Threads. Timer a également une action de thread, mais il est assez facile à comprendre de l'utiliser.

 0
Author: Bill Vouronikos, 2018-07-24 18:37:25