# Kurzer Timer



## Tacofan (3. Mrz 2016)

Hallo,

ich suche einen Timer der z.B. 100sek geht und sobald diese 100sek abgelofen sind sollte etwas passieren. Habe hier ein Code dazu! Aber dieser geht leider nicht....
Weiß jemand was?


```
int mZaehler=0;
            lbGif.setVisible(true);
           
            while(100>mZaehler)
            {
                mZaehler=mZaehler+1;
            }
            if(mZaehler>100)
            {
                lbGif.setVisible(false);
            }
```


----------



## strußi (3. Mrz 2016)

du hast den fall, das dein zähler 100 erreicht und danacht die while-schleife beendet wird. die if fragt aber ab ob echt größer 100
einfach mZaehler >=100 dann erhälst du dein gewünschtes ergebnis


----------



## kneitzel (3. Mrz 2016)

Und das ein Durchgang auch nicht 1 Sekunde dauert, so dass dies kein 100 Sekunden warten bedeutet. Und wenn es nur um ein Warten geht, dann würde ich das auch nicht mit Aktionen machen, die CPU belegen.


----------



## strußi (3. Mrz 2016)

du könntest das mit dem befehl wait( timeInMs) machen


----------



## Schesam (3. Mrz 2016)

Gibt dafür die Klasse Timer und TimerTask:

```
Timer timer = new Timer("Zähler");
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println("100 Sekunden gewartet!");
            }
        };
        timer.schedule(task, TimeUnit.SECONDS.toMillis(100));
```

Könnte dein gewünschtes sein. Kannst auch etwas periosdisch mit nem festgelegtem Delay machen mit scheduleAtFixedRate


----------



## RalleYTN (7. Mrz 2016)

```
long startTimer = System.currentTimeMillis();
long updateTimer = 0;

while(/*Hier Bedingung eingeben*/) {
    updateTimer = System.currentTimeMillis();
    if(updateTimer - startTimer >= (sec * 1000)) {
          // Aktion hier durchführen.
    }
}
```


----------



## kneitzel (7. Mrz 2016)

Also der Code soll aktiv warten, bis eine gewisse Zeit verstrichen ist? Halte ich für recht extrem, da hier ja massiv CPUs belastet werden. Das ist doch mit Multitasking und so nun wirklich nicht mehr Zeitgemäß. Man kann ja ein System mal 30 Sekunden so warten lassen und dabei die CPU Nutzung betrachten:


```
long startTimer =System.currentTimeMillis();
long updateTimer;
boolean continueLoop = true;
int sec = 30;

while(continueLoop){
    updateTimer =System.currentTimeMillis();
   if(updateTimer - startTimer >=(sec *1000)){
         continueLoop = false;
   }
}
```

Damit zieht man dann einen CPU Kern schön auf Last für eigentlich nichts und wieder nichts. Oder habe ich da jetzt etwas missverstanden?


----------



## mrBrown (9. Mrz 2016)

kneitzel hat gesagt.:


> Damit zieht man dann einen CPU Kern schön auf Last für eigentlich nichts und wieder nichts. Oder habe ich da jetzt etwas missverstanden?



Hast du genau richtig verstanden, wenn schon so einen Loop, dann mit Thread.sleep(). Noch unsinniger ist aber das auch vorgeschlagene wait( timeInMs)...

Am klügsten ist in den meisten Fällen die Verwendung von Timer und TimerTask


----------



## Kababär (11. Mrz 2016)

Mal eine Verständnisfrage. 
Wozu soll ich Programm an einem Punkt festhalten für eine gewisse Zeit? 
Sofern man währenddessen intern keine Methoden aufrufen kann oder ähnliches wüsste ich nicht, wieso man das machen sollte, aber die Vielfalt an Möglichkeiten, dies zu realisieren, deutet schon darauf hin, auch historisch, dass es oft benötigt wird. 

Kann mir da mal jemand helfen?


----------



## Schesam (11. Mrz 2016)

Das Programm kurz anzuhalten mit Thread.sleep() etc gibt schon oft sinn, meistens aber nur wenn man in mehreren Threads arbeitet. z.B. wenn man einen CLip benutzt und damit AudioDateien abspielt, kann man das Programm warten lassen, bis der Clip zuende abgespielt wurde und dann weitermachen lassen, da der CLip in nem anderen Thread läuft würde das Programm sonst sofort weitermachen und z.B. mehrere Lieder gleichzeitig abspielen, was sehr unschön ist.

Ein Anwendungsfall für den Timer wäre z.B. das hier:

```
private void startTimer() {
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss", Locale.GERMANY);
                timeLabel.setText(sdf.format(System.currentTimeMillis()));
            }
        };
        new Timer("Uhr").scheduleAtFixedRate(task, 0, TimeUnit.SECONDS.toMillis(1));
    }
```
Damit wird jede Sekunde der Text meines "timeLabel" erneuert, um die momentane Uhrzeit anzuzeigen.


----------



## mrBrown (11. Mrz 2016)

Schesam hat gesagt.:


> Das Programm kurz anzuhalten mit Thread.sleep() etc gibt schon oft sinn, meistens aber nur wenn man in mehreren Threads arbeitet. z.B. wenn man einen CLip benutzt und damit AudioDateien abspielt, kann man das Programm warten lassen, bis der Clip zuende abgespielt wurde und dann weitermachen lassen, da der CLip in nem anderen Thread läuft würde das Programm sonst sofort weitermachen und z.B. mehrere Lieder gleichzeitig abspielen, was sehr unschön ist.



Thread.sleep zur Synchronisation ist meistens grober Unfug...

Im Grunde ist der Sinn von Sleep einfach nur, kurz zu warten. Für die meisten Nutzungsmöglichkeiten gibts aber grad in Java geeignetere Dinge.


----------



## kneitzel (11. Mrz 2016)

Also Beispiele fallen mir viele ein. Ein typisches Beispiel kann sein: Es ist ein Fehler aufgetreten und Du willst nach kurzem Warten es erneut probieren.
Aber man sollte immer genau das generelle Design im Kopf behalten. Und es macht immer Sinn, die generellen Möglichkeiten im Hinterkopf zu haben um eben möglichst sauber im Design zu bleiben.


----------



## Kababär (11. Mrz 2016)

Also generell macht dann ein wait()/sleep() w/e meist nur im Bereich von Client-Server-Prinzipien, in der der Server die Schnittstelle aller Clients ist. Beispielsweise Login, Datenbankabfragen, etc, um die Prozessor/Speicherlast auf einen guten Durchschnitt zu bringen bzw. Überlastung zu vermeiden?

Alternativ zu diesem Sleep/wait wäre doch auch einfach eine boolsche Variable verwendbar a la 

```
if(isDone){
...
}
```
oder was ich gerne mache, ist einfach eine Verkettung von Methoden oder serielles Aufrufen von Methoden

```
Verkettung:
public void m1(){
.....
m2();
}

public void m2(){
...
m3();
}

Seriell:
public void callMethods(){
m1();
m2();
m3();
}
```

Hier könnte man keinen Timer benutzen? Jeder Rechner arbeitet ja unterschiedlich schnell und so würde man ggf. schnelle Rechner warten lassen, während es bei langsameren Rechnern zu Fehlern führen könnte?


----------



## kneitzel (11. Mrz 2016)

Also bei Client-Server Anwendungen findet das kaum Anwendung, denn bei Anfragen an den Server kann ein Sync-Call verwendet werden, d.h. im Thread wird einfach vom Netzwerk gelesen und das blockiert schon bis die Daten da sind.

Ein Thread.Sleep ist generell eine Sache, die recht selten vorkommt. Im Augenblick kann ich mich nicht erinnern, wo ich das zuletzt verwendet habe.

Bezüglich der Aufrufe von Funktionen: Wenn Dinge hintereinander ausgeführt werden sollen aber m1, m2 und m3 voneinander unabhängig sind, dann macht es keinen Sinn, diese ineinander aufzurufen. Das ist aber dann nur für das bessere Verständnis vom Code. Und es könnte auch genau anders herum sein.


----------



## Xyz1 (11. Mrz 2016)

Ich hätte es ja so gemacht:

```
private static long waitBusy1() {
        long t1 = System.currentTimeMillis();
        long l = 0;
        while (l < 10000000) {
            l++;
        }
        long t2 = System.currentTimeMillis();
        return (long) (l / ((t2 - t1) / 1000.0));
    }

    private static void waitBusy2() {
        long stop = waitBusy1();
        long l = 0;
        while (l < stop) {
            l++;
        }
    }

    private static void waitBusy3(int sec) {
        while (sec > 0) {
            waitBusy2();
            sec--;
        }
    }

    public static void main(String[] args) {
        long t1 = System.currentTimeMillis();
        waitBusy3(5);
        long t2 = System.currentTimeMillis();
        System.out.println((t2 - t1));
    }
```

Wartet busy 5 Sekunden. Optimierungen vielleicht ausschalten.


----------



## Kababär (11. Mrz 2016)

Alles klar danke dir


----------



## Xyz1 (11. Mrz 2016)

Eigentlich müsste jetzt ja erwartet werden, dass etwas mehr als 5 Sek. gewartet wird, wegen dem Ermitteln 1 Sek., das tut's aber nicht, weil diese Schleife einfach zu schnell ist.


----------



## Meniskusschaden (11. Mrz 2016)

DerWissende hat gesagt.:


> Ich hätte es ja so gemacht:
> 
> ```
> private static long waitBusy1() {
> ...


Ich wüsste jetzt nicht, warum man überhaupt aktives Warten einsetzen sollte. Oben gab es ja bereits einige Hinweise, wie man CPU-schonend warten kann. Wenn man es aber trotzdem unbedingt machen möchte, scheint mir diese Implementierung zu aufwändig und zu ungenau zu sein. Anstatt zu versuchen, vorab die nötigen Schleifendurchläufe zu ermitteln, kann man doch einfach direkt in der Warteschleife die Laufzeit überprüfen:

```
public static void busyWait(int seconds) {
        long endZeitpunkt = System.currentTimeMillis() + seconds*1000;
        while (System.currentTimeMillis() < endZeitpunkt);
}
```


----------



## Xyz1 (11. Mrz 2016)

Meniskusschaden hat gesagt.:


> Anstatt zu versuchen, vorab die nötigen Schleifendurchläufe zu ermitteln, kann man doch einfach direkt in der Warteschleife die Laufzeit überprüfen:



Ja, ist fast jacke wie hose.


----------



## mrBrown (11. Mrz 2016)

DerWissende hat gesagt.:


> Ja, ist fast jacke wie hose.



Wenn man mit der Unübersichtlichkeit, Ungenauigkeit und Fehleranfälligkeit leben kann, ist das Jacke wie Hose, die meisten mögen's aber lieber anders


----------



## Xyz1 (11. Mrz 2016)

Von Fehlerlosigkeit bei beschäftigtem Warten zu sprechen ist an sich schon lustig genug...


----------



## tom2208 (15. Mrz 2016)

RalleYTN hat gesagt.:


> ```
> long startTimer = System.currentTimeMillis();
> long updateTimer = 0;
> 
> ...


wenn du 100sec nicht genau brauchst kannst du dem programm etwas rechenleistung entziehen indem du Thread.sleep(20); o.ä. mit einbaust


----------



## Saheeda (15. Mrz 2016)

Kababär hat gesagt.:


> Mal eine Verständnisfrage.
> Wozu soll ich Programm an einem Punkt festhalten für eine gewisse Zeit?
> Sofern man währenddessen intern keine Methoden aufrufen kann oder ähnliches wüsste ich nicht, wieso man das machen sollte, aber die Vielfalt an Möglichkeiten, dies zu realisieren, deutet schon darauf hin, auch historisch, dass es oft benötigt wird.
> 
> Kann mir da mal jemand helfen?


Typischer Anwendungsfall bei uns sind GUI-Tests via Selenium. Mitunter will der Test schon klicken, obwohl der entsprechende Button / die Tabelle noch gar nicht geladen ist. 
Oder beim Testen von Mailservices (Greenmail) geben wir auch eine Wartezeit vor, innert welcher eine Mail eintrudeln sollte.
Beides absolute Spezialfälle, aber bei uns doch schon häufiger.


----------

