TimerTask Scheduler

mci

Grünschnabel
Hallo zusammen,

ich habe eine Frage bezüglich Job Scheduling.

Ich habe ein fixes 3 Minuten Zeitintervall, indem ich ein Thread ausführen möchte.
Und zwar folgendes: 00:00 | 00:03 | 00:06 | 00:09 | 00:12 | 00:15 | 00:18 usw. bis zur nächsten Stunde.

In diesen Minuten soll ein Thread aufgerufen werden, egal um welche Stunde es sich handelt. Es kann auch 13:00 | 13:03 | 13:06 | 13:09 oder 23:15 | 23:18 | 23:21 das ist egal solange der Thread in dem Drei- Minutenintervall ausgeführt wird.

Nun zum Problem, dass ich nicht lösen kann. Wenn ich das Programm z.B um 14:04 einschalte, wie kann ich die Zeit berechnen, sodass mein Thread um 14:06 Uhr startet und dann jeweils alle 3 Minuten weiter ausgeführt wird?

Ich habe einen Lösungsansatz (soweit man das ein Ansatz nennen kann) mit Timer und TimerTask, so wie es z.B im OpenBook beschrieben ist.

TimerTask dreiMinuten = new DreiMin();
Timer timer = new Timer();
timer.schedule(dreiMinuten, long xxx, 180000);

Was ich suchen würde, wäre xxx.

Ich habe versucht mir den Quartz Scheduler zu Gemüte zuführen, bin aber kläglich gescheitert, da es kaum Dokumentation auf Deutsch gibt.

Kann mir vielleicht jemand helfen?
Danke im vorraus.

Lg mci
 
du musst doch nur die akutelle Stunde nehmen, immer deine 3 Minuten draufrechnen und schauen ob deine akutelle Zeit drunter oder drüber liegt. Liegt sie drunter kannst du die Differenz berechnen, liegt sie drüber addierst du auf die Stunde solange 3 Minuten bis die aktuelle Zeit kleiner ist. Das ganze natürlich in Millisekunden und schon solltest du es haben oder irre ich da
 
Hallo,

schau mal hier:
Java:
package de.tutorials;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class TimedExecutionExample {
    public static void main(String[] args) {
        GregorianCalendar now = new GregorianCalendar();
        int remainingMinutes = (now.get(Calendar.MINUTE) / 3 + 1) * 3 - now.get(Calendar.MINUTE) - 1;
        int remainingSeconds = 60 - now.get(Calendar.SECOND);
        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(
                new Runnable() {
                    public void run() {
                        System.out.println("Work: @" + new Date());
                    }
                }, 
                remainingMinutes * 60 + remainingSeconds, 
                180,
                TimeUnit.SECONDS
        );
    }
}

Gruß Tom
 
@ normaler_spinner
Danke, guter Ansatz!

@Thomas Darimont
Danke vielmals. So simple kann die Lösung sein! Das ist ein Zeichen dafür, dass ich das nächste Mal etwas länger nachdenken muss. ;) Nochmals danke!

Lg mci

Edit: @Thomas Darimont
Hallo Thomas, wie kommst Du auf diesen "Algorithmus"? Ich meine, kannst Du das mathematisch erklären?
now.get(Calendar.MINUTE) / 3 + 1) * 3

Danke im vorraus
 
Zuletzt bearbeitet:
Hallo,

schau mal hier:

int remainingMinutes = (now.get(Calendar.MINUTE) / 3 + 1) * 3 - now.get(Calendar.MINUTE) - 1;

Beispiel 10:40:45 Uhr:


now.get(Calendar.MINUTE) -> 40
now.get(Calendar.SECOND) -> 45

now.get(Calendar.MINUTE) / 3 (ganzzahl division!) -> 13
13 * 3 -> 39 = Die letzte (vergangene) ohne Rest durch 3 teilbare Minute

now.get(Calendar.MINUTE) / 3 + 1-> 14
14 * 3 -> 42 -> Die nächste (kommende) ohne Rest durch 3 teilbare Minute.

Also:
42 - 40 = 2 Minuten bis zur nächsten ohne Rest durch 3 teilbaren Minute.
Da eine Minute davon jedoch schon angebrochen ist müssen wir diese abziehen.

Also 2 - 1 = 1 Minute + 15 Sekunden bis zur nächsten vollen ohne Rest durch 3 teilbaren Minute -> 10:42:00

60 - 45 -> 15 Sekunden

Gruß Tom
 
Hallo,
int remainingMinutes = (now.get(Calendar.MINUTE) / 3 + 1) * 3 - now.get(Calendar.MINUTE) - 1;

nebenbei, noch eine Variante
Code:
int mins = new GregorianCalendar().get(Calendar.MINUTE);
int remaining_minutes = (3 - (mins % 3))  % 3;

Das letzte %3 nochmal hinten dran damit er bei durch 3 teilbaren Zahlen sofort startet und nicht erst in 3 Minuten.

Gruß,
RedWing
 
Zurück