Maak een eenvoudige timer in Java

Ik kan er niet achter komen hoe ik een eenvoudige timer in Java kan maken. Ik heb het alleen nodig om de tijd weer te geven, echt waar. Dus gewoon een startmethode, en het blijft optellen als 0:00, 0:01, 0:02, enz. Ik heb een aantal andere soortgelijke forumberichten hierover gezien, maar alle code is nogal ingewikkeld voor mijn niveau van begrip; Ik ben een beetje nieuw in java. Maar het zou toch niet zo moeilijk moeten zijn om een timer te maken die zo’n basisfunctie vervult? Als iemand zou kunnen helpen, zou dat zeer op prijs worden gesteld 🙂


Antwoord 1, autoriteit 100%

Dit is niet moeilijk. Ik wil je echter waarschuwen dat ik een aantal zeer verwarde antwoorden heb gezien over stack-overflow, in sommige gevallen schokkend slechte codeergewoonten, dus wees heel voorzichtig. Laat me eerst de vraag beantwoorden.

Het lijkt erop dat de grootste fout die programmeurs maken bij het implementeren van een timer, is te denken dat ze iets nodig hebben om de huidige tijd bij te houden. Dat wil zeggen, ze schrijven een soort lus die elke seconde een variabele verhoogt of iets dergelijks. U hoeft geen code te schrijven om de tijd bij te houden. De functie System.currentTimeMillis()zal dat voor je doen, en het doet het vrij nauwkeurig.

Timercode omvat twee aspecten die veel programmeurs door elkaar halen:

  1. berekening van de tijd
  2. vernieuwing van het scherm

Het enige dat u hoeft te doen om de weergegeven tijd te berekenen, is de tijd te noteren waarop de timer begon:

long startTime = System.currentTimeMillis();

Als u later de hoeveelheid tijd wilt weergeven, trekt u deze gewoon van de huidige tijd af.

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

De grootste fout die programmeurs maken, is te denken dat ze een variabele nodig hebben om de huidige tijd vast te houden en vervolgens code te schrijven om die variabele elke seconde te verhogen, b.v. iets dat “elapsedSeconds” wordt genoemd en dat ze onderhouden. Het probleem is dat je kunt plannen dat de code elke seconde wordt aangeroepen, maar er is geen garantie dat die code precies wordt aangeroepen. Als het systeem bezet is, kan die code een stuk later dan de tweede worden opgeroepen. Als het systeem extreem druk is (bijvoorbeeld het ophalen van pagina’s van een defecte schijf), kan het enkele seconden te laat zijn. Code die de functie Thread.sleep(1000) gebruikt om elke seconde een lus te maken, zal merken dat de fout zich in de loop van de tijd opbouwt. Als de slaap een keer 300 ms te laat terugkeert, wordt die fout verergerd in uw berekening van hoe laat het is. Dit is allemaal helemaal niet nodig omdat het besturingssysteem een functie heeft om u de huidige tijd te vertellen.

De bovenstaande berekening is nauwkeurig, of u deze code nu elke seconde, 100 keer per seconde of elke 3,572 seconden uitvoert. Het punt is dat currentTimeMillis()de nauwkeurige weergave van de tijd is, ongeacht wanneer deze code wordt aangeroepen — en dat is een belangrijke overweging omdat thread- en timergebeurtenissen niet gegarandeerd nauwkeurig zijn op een specifieke tijd.

Het tweede aspect van een timer is het verversen van het scherm. Dit hangt af van de technologie die u gebruikt om mee weer te geven. In een GUI-omgeving moet u verfgebeurtenissen plannen. U wilt dat deze verfgebeurtenissen plaatsvinden direct na het tijdstip waarop de weergave naar verwachting zal veranderen. Het is echter lastig. U kunt een verfgebeurtenis aanvragen, maar er kunnen honderden andere verfgebeurtenissen in de wachtrij staan om vóór die van u te worden afgehandeld.

Een luie manier om dit te doen, is door 10 verfgebeurtenissen per seconde te plannen. Omdat de berekening van de tijd niet afhankelijk is van de code die op een bepaald tijdstip wordt aangeroepen, en omdat het niet uitmaakt of u het scherm met dezelfde tijd opnieuw schildert, garandeert deze benadering min of meer dat de weergegeven tijd laat de juiste tijd zien binnen ongeveer 1/10 van een seconde. Dit lijkt een beetje zonde, want 9 van de 10 keer schilder je wat er al op het scherm staat.

Als je een programma schrijft met een soort animatie (zoals een spel) dat het scherm 30 keer per seconde ververst, hoef je niets te doen. Neem gewoon de timerweergave-oproep op in uw normale schermvernieuwing.

Als verfgebeurtenissen duur zijn, of als u een programma schrijft dat uitvoer in terminalstijl uitvoert, kunt u de planning van gebeurtenissen optimaliseren door de resterende tijd te berekenen totdat de weergave verandert:

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

De variabele timeTillNextDisplayChange bevat het aantal milliseconden dat je moet wachten totdat het secondengedeelte van de timer verandert. U kunt dan een paint-gebeurtenis plannen die op dat moment plaatsvindt, mogelijk door Thread.sleep(timeTillNextDisplayChange)aan te roepen en na de slaap de uitvoer te doen. Als uw code in een browser wordt uitgevoerd, kunt u deze techniek gebruiken om de pagina-DOM op het juiste moment bij te werken.

Merk op dat er niets in deze berekening van de schermvernieuwing is dat de nauwkeurigheid van de timer zelf beïnvloedt. De thread kan 10 ms te laat of zelfs 500 ms te laat terugkeren uit de slaapstand, en de nauwkeurigheid van de timer wordt niet beïnvloed. Bij elke pas berekenen we de wachttijd uit de currentTimeMillis, dus als u de ene keer te laat wordt gebeld, zullen latere weergaven niet te laat zijn.

Dat is de sleutel tot een nauwkeurige timer. Verwacht niet dat het besturingssysteem uw routine oproept of de verfgebeurtenis verzendt precies wanneer u daarom vraagt. Meestal is het besturingssysteem natuurlijk, met moderne machines, opmerkelijk responsief en nauwkeurig. Dit gebeurt in testsituaties waar je niet veel anders loopt en de timer lijkt te werken. Maar in productie, onder zeldzame stresssituaties, wil je niet dat je timer “afdrijft” omdat het systeem druk is.


Antwoord 2

Je kunt de klasse Timervan java.utilgebruiken of op een andere manier, die ingewikkelder is, is met Threads. Timer heeft ook thread-actie, maar het is vrij eenvoudig te begrijpen om het te gebruiken.


Antwoord 3

Voor het maken van een eenvoudige timer, zoals je hebt uitgelegd, is het heel eenvoudig om daarvoor een code te schrijven. Ik heb de onderstaande code voor uw referentie geschreven. Als je wilt, kun je het verbeteren.

java.util.concurrent.TimeUnit importeren;
openbare les PerfectTimer {

public static void main(String[] args) throws InterruptedException 
{
    boolean x=true;
    long displayMinutes=0;
    long starttime=System.currentTimeMillis();
    System.out.println("Timer:");
    while(x)
    {
        TimeUnit.SECONDS.sleep(1);
        long timepassed=System.currentTimeMillis()-starttime;
        long secondspassed=timepassed/1000;
        if(secondspassed==60)
        {
            secondspassed=0;
            starttime=System.currentTimeMillis();
        }
        if((secondspassed%60)==0)
        displayMinutes++;
    System.out.println(displayMinutes+"::"+secondspassed);
    }
}

}

Other episodes