Frage

Mein Programm hat eine Komponente - der Scheduler genannt -, die anderen Komponenten registrieren Zeitpunkt kann, an den sie wollen, zurückgerufen werden. Dies sollte ähnlich wie der Unix cron Dienst arbeiten, ich. e. Sie Scheduler sagen, „informieren Sie mich in zehn Minuten nach jeder vollen Stunde“.

Ich weiß, gibt es keine echten Rückrufe in Java.

Hier ist mein Ansatz gibt es eine Bibliothek, die bereits das Zeug tut? Sie können ferner Verbesserungen vorzuschlagen, zu.

Register Aufruf Scheduler übergibt:

  • eine Zeitangabe enthält, Stunde, Minute, Sekunde, Jahr Monat, dom, dow, wobei jedes Element nicht spezifiziert sein kann, was bedeutet, „führen Sie es jede Stunde / Minute usw.“ (Wie crontabs)
  • ein Objekt mit Daten, die der Berufung erzählen Objekt, was zu tun ist, wenn es durch den Scheduler mitgeteilt wird. Der Scheduler diese Daten nicht verarbeiten, speichert es und geht es zurück nach Benachrichtigung.
  • ein Verweis auf das aufrufende Objekt

Nach dem Start oder nach einer neuen Registrierungsanforderung, startet der Scheduler mit einem Kalender-Objekt der aktuellen Systemzeit und prüft, ob es irgendwelche Einträge in der Datenbank, die zu diesem Zeitpunkt entsprechen. Wenn ja, werden sie ausgeführt, und der Prozess beginnt von vorne. Wenn es nicht, wird die Zeit im Kalender Objekt um eine Sekunde erhöht und die entreis erneut überprüft werden. Dies wiederholt sich, bis es einen Eintrag oder mehr, die Ergebnis (se). (Discrete Event Simulation)

erinnern

Der Scheduler wird dann den Zeitstempel, Schlaf- und Wach jede Sekunde zu überprüfen, ob es schon da ist. Wenn es passiert, aufzuwachen und die Zeit ist schon vergangen, es beginnt über, ebenfalls, wenn die Zeit gekommen ist und die Aufträge ausgeführt wurden.


Bearbeiten : Danke für mich Quartz zeigt. Ich suche nach etwas viel kleiner, aber.

War es hilfreich?

Lösung

Wenn sich Ihre Bedürfnisse einfach sind, sollten Sie mit java rel="nofollow .util.Timer :

public class TimerDemo {

  public static void main(String[] args) {
    // non-daemon threads prevent termination of VM
    final boolean isDaemon = false;
    Timer timer = new Timer(isDaemon);

    final long threeSeconds = 3 * 1000;
    final long delay = 0;
    timer.schedule(new HelloTask(), delay, threeSeconds);

    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.MINUTE, 1);
    Date oneMinuteFromNow = calendar.getTime();

    timer.schedule(new KillTask(timer), oneMinuteFromNow);
  }

  static class HelloTask extends TimerTask {
    @Override
    public void run() {
      System.out.println("Hello");
    }
  }

  static class KillTask extends TimerTask {

    private final Timer timer;

    public KillTask(Timer timer) {
      this.timer = timer;
    }

    @Override
    public void run() {
      System.out.println("Cancelling timer");
      timer.cancel();
    }
  }

}

Wie bereits bemerkt , die ExecutorService von < a href = "http://java.sun.com/javase/6/docs/api/java/util/concurrent/package-frame.html" rel = "nofollow noreferrer"> java.util.concurrent bietet eine reichere API, wenn Sie es brauchen.

Andere Tipps

Wenn Sie Ihre Objekte genau wissen, die einzelnen Punkte in der Zeit, die sie wollen, ausgeführt werden, dann könnten Sie eine java.util.concurrent.ScheduledExecutorService verwenden. Dann werden sie einfach Aufruf:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
long timeToExecute = ... //read from DB? use CronTrigger?
long delayToExecution = timeToExecute - System.currentTimeMillis();
scheduler.schedule(aRunnable, delayToExecution, TimeUnit.MILLISECONDS);

Sie würden nur Quartz verwenden müssen, wenn Sie der Planer selbst wollen zu handhaben Funktionalität wie „alle 5 Sekunden ausführen“, oder wenn Sie komplexes Verhalten um verpasste Hinrichtung wollen, oder die Persistenz der Ausführung Audit-Trail.

Sie können tatsächlich triviale Weise wiederverwenden Quartz des CronTrigger Klasse eine „nächste Ausführungszeit“ zu erhalten. Die Klasse ist völlig eigenständige und hängt nicht von innerhalb des Quartz „Kontext“ aufgerufen wird. Sobald Sie die nächste Ausführungszeit als Date oder long haben, können Sie einfach die Java verwenden ScheduledExecutorService wie oben

Quartz ist das große und offensichtliches Kraftwerk in diesem Bereich, aber es gibt einige Alternativen zu erkunden .

Cron4j ist eine anständige genug Bibliothek, das ist ein wenig leichter als Quarz ist. Es bietet eine gute Dokumentation und das tun, was Sie wollen.

Wahrscheinlich ist interessanter, wenn Sie eine Bibliothek verwenden möchten, die mit Java Concurrency Bibliotheken besser passt (insbesondere Testamentsvollstrecker und ScheduledExecutors) dann HA-JDBC eine CronExecutorService Schnittstelle, implementiert durch den

Ich würde empfehlen, cron4j (bereits erwähnt) über Quarz, es sei denn, Sie unbedingt benötigen einige erweiterte und komplexe Funktionen von Quarz. Cron4j konzentriert sich schön auf, was es tun soll, hat ordentliche Dokumentation und ist keine Küchenspüle Lösung.

Quartz Scheduler wird in der Regel empfohlen.

Kann nicht glauben, java.util.Timer wurde als Antwort gewählt. Quarz ist wirklich eine viel bessere Wahl.

Ein großer Vorteil von Quarz über java.util.Timer ist mit Quarz, dass die Arbeitsplätze in der DB gespeichert werden können. Als Ergebnis kann man Jvm planen und andere ausführen kann. Auch (natürlich) die Anfrage überlebt über Jvm neu gestartet wird.

  

Wahrscheinlich ist interessanter, wenn Sie eine Bibliothek verwenden möchten, die mit Java Concurrency Bibliotheken besser passt (insbesondere Testamentsvollstrecker und ScheduledExecutors) dann HA-JDBC hat eine CronExecutorService Schnittstelle, durch seine CronThreadPoolExecutor umgesetzt. Nun Interessanterweise hat es eine Abhängigkeit von Quartz (die CronExpression Klasse liefern), aber ich finde, dass die beiden zusammen besser arbeiten als nur Quarz allein. Wenn Sie keine großen Abhängigkeiten wollen, ist es einfach, die Handvoll von Klassen aus Quarz und HA-JDBC zu extrahieren, damit dies geschieht.

Ich wollte nur sagen, dass ich diese Klassen versucht zu extrahieren, und es funktionierte! Ich brauchte diese drei Klassen:

  • CronExpression (Quarz)
  • CronThreadPoolExecutor (ha-jdbc)
  • DaemonThreadFactory (ha-jdbc)

Und ich hatte nur diese kleineren Verbesserungen zu tun:

  • Entfernen des Loggers von CronThreadPoolExecutor (es erstellt wurde, aber nie benutzt)
  • Verschoben die Konstante YEAR_TO_GIVEUP_SCHEDULING_AT von CronTrigger zu CronExpression

Ich war begeistert, dass ich nicht stecken Pull in einem Gewirr von Abhängigkeiten erhalten habe. Wir gratulieren den Klassen Autoren!

Und es hat sich wie ein Champion zu arbeiten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top