43 Stimmen

Wie kann ich meine TimerTask täglich um 14 Uhr ausführen?

Ich möchte jeden Tag um 14 Uhr einen Auftrag ausführen. Welche Methode der java.util.Timer die ich zur Planung meines Auftrags verwenden kann?

Nach 2 Stunden Laufzeit wird der Auftrag gestoppt und für den nächsten Tag um 2 Uhr nachmittags neu angesetzt.

75voto

Daniel Gerber Punkte 2902
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 2);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);

// every night at 2am you run your task
Timer timer = new Timer();
timer.schedule(new YourTask(), today.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); // period: 1 day

23voto

hmjd Punkte 118293

Sie könnten verwenden Timer.schedule(TimerTask task, Date firstTime, long period) Methode, Einstellung firstTime auf 2PM heute und die Einstellung der period bis 24 Stunden:

Plant die angegebene Aufgabe zur wiederholten Ausführung mit fester Verzögerung, beginnend zum angegebenen Zeitpunkt. Nachfolgende Ausführungen finden in ungefähr regelmäßigen Abständen statt, die durch den angegebenen Zeitraum getrennt sind.

15voto

BOSS Punkte 2881
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Timer;
import java.util.TimerTask;

public class MyTimerTask extends TimerTask {
    private final static long ONCE_PER_DAY = 1000*60*60*24;

    //private final static int ONE_DAY = 1;
    private final static int TWO_AM = 2;
    private final static int ZERO_MINUTES = 0;

    @Override
    public void run() {
        long currennTime = System.currentTimeMillis();
        long stopTime = currennTime + 2000;//provide the 2hrs time it should execute 1000*60*60*2
          while(stopTime != System.currentTimeMillis()){
              // Do your Job Here
            System.out.println("Start Job"+stopTime);
            System.out.println("End Job"+System.currentTimeMillis());
          }
    }
    private static Date getTomorrowMorning2AM(){

        Date date2am = new java.util.Date(); 
           date2am.setHours(TWO_AM); 
           date2am.setMinutes(ZERO_MINUTES); 

           return date2am;
      }
    //call this method from your servlet init method
    public static void startTask(){
        MyTimerTask task = new MyTimerTask();
        Timer timer = new Timer();  
        timer.schedule(task,getTomorrowMorning2AM(),1000*10);// for your case u need to give 1000*60*60*24
    }
    public static void main(String args[]){
        startTask();

    }

}

5voto

Ali Punkte 12084

Der einfachste Weg, dies zu tun, war immer der Taskplaner in Windows und cron in Linux.

Für Java sollten Sie jedoch einen Blick auf Quarz-Scheduler

Von ihrer Website:

Quartz ist ein vollwertiger, quelloffener Job Scheduling Service, der in praktisch jede Java EE- oder Java SE-Anwendung integriert oder neben ihr verwendet werden kann. SE-Anwendung - von der kleinsten Standalone-Anwendung bis zur größten E-Commerce-System. Quartz kann verwendet werden, um einfache oder komplexe Zeitpläne für die Ausführung von Dutzenden, Hunderten oder sogar von Tausenden von Jobs; Jobs, deren Aufgaben als Standard Java-Komponenten definiert sind, die virtuell ausgeführt werden können programmieren. Der Quartz Scheduler enthält viele Enterprise-Class Funktionen, wie JTA-Transaktionen und Clustering.

4voto

Mr. Ree Punkte 873

Die meisten Antworten auf diese Frage und die beiden folgenden Fragen davon ausgehen, dass die Millisekunden pro Tag immer gleich sind .
Wie plant man eine periodische Aufgabe in Java?
Wie kann man eine bestimmte Aufgabe jeden Tag zu einer bestimmten Zeit mit ScheduledExecutorService ausführen?

Dies ist jedoch aufgrund der Sommerzeit und der Schaltsekunden nicht richtig. Das bedeutet, dass, wenn Ihr Dienst jahrelang läuft und die Genauigkeit der Zeitschaltuhr wichtig ist, ist eine Zeitschaltuhr mit fester Zeitdauer nicht die richtige Wahl.

Daher möchte ich meinen Codeschnipsel für einen flexibleren Timer als den java.util.Timer .

package szx;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.function.Function;

public class ScheduledExecutor {
  public void scheduleRegularly(Runnable task, LocalDateTime firstTime,
                                Function<LocalDateTime, LocalDateTime> nextTime) {
    pendingTask = task;
    scheduleRegularly(firstTime, nextTime);
  }

  protected void scheduleRegularly(LocalDateTime firstTime,
                                   Function<LocalDateTime, LocalDateTime> nextTime) {
    new Timer().schedule(new TimerTask() {
      @Override
      public void run() {
        scheduleRegularly(nextTime.apply(firstTime), nextTime);
        pendingTask.run();
      }
    }, Date.from(firstTime.atZone(ZoneId.systemDefault()).toInstant()));
  }

  private volatile Runnable pendingTask = null;
}

Dann können Sie Ihren Auftrag täglich um 2 Uhr nachmittags ausführen, indem Sie die oben genannte Methode wie folgt aufrufen.

new ScheduledExecutor().scheduleRegularly(() -> {

    // do your task...

}, LocalDateTime.now().truncatedTo(ChronoUnit.DAYS).withHour(14), thisTime -> thisTime.plusDays(1));

Die Grundidee hinter dem Code ist es, die verbleibende Zeit bis zum nächsten Tick neu zu berechnen und jedes Mal einen neuen Timer zu starten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X