web-dev-qa-db-fra.com

Comment puis-je exécuter ma TimerTask tous les jours 2 PM

Je veux exécuter un travail tous les jours à 14h. Quelle méthode de Java.util.Timer que puis-je utiliser pour planifier mon travail?

Après l'exécution de 2 heures, il arrêtera le travail et sera reprogrammé pour 14 heures le lendemain.

34
BOSS
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();

    }

}
15
BOSS
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
55
Daniel Gerber

Vous pouvez utiliser la méthode Timer.schedule(TimerTask task, Date firstTime, long period), en définissant firstTime sur 2PM aujourd'hui et en définissant period sur 24 heures:

Planifie la tâche spécifiée pour une exécution répétée à délai fixe, en commençant à l'heure spécifiée. Les exécutions suivantes ont lieu à intervalles approximativement réguliers, séparés par la période spécifiée.

23
hmjd

La façon la plus simple que j'ai trouvée de le faire a toujours été d'utiliser le Planificateur de tâches sous Windows et cron sous Linux.

Cependant pour Java, jetez un œil à Quartz Scheduler

Depuis leur site Web:

Quartz est un service de planification de tâches open source complet qui peut être intégré ou utilisé à côté de pratiquement n'importe quel Java EE ou Java SE) - à partir de la plus petite application autonome du plus grand système de commerce électronique. Quartz peut être utilisé pour créer des planifications simples ou complexes pour exécuter des dizaines, des centaines, voire des dizaines de milliers de tâches; tâches dont les tâches sont définies comme standard Java qui peuvent exécuter pratiquement tout ce que vous pouvez leur programmer. Quartz Scheduler comprend de nombreuses fonctionnalités de classe entreprise, telles que les transactions JTA et le clustering.

4
Ali

Vous devriez essayer d'utiliser scheduleAtFixedRate (cela répétera votre tâche). Vous devrez créer un objet TimerTask qui spécifiera ce qu'il faut exécuter (dans run ()) et quand l'exécuter (schedExecutionTime). ScheduleAtFixedRate vous permet également de spécifier la première date d'exécution.

3
MilkDoctrine

Pourquoi n'utilisez-vous pas Spring's @Scheduled (cron = "0 0 14 * * *") .. for sec, min, hours, day, month, dayOfWeek. V Cool. Vous pouvez même spécifier 9-11 pour 9:00 à 11:00 ou MON-FRI dans le dernier paramètre. Vous pouvez également l'invoquer par programme, comme c'est le cas pour la plupart de Spring, au cas où vous voudriez régler l'heure à l'exécution. Voir ceci: - http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html

Ajout d'un exemple

   @Scheduled(cron="0 0 14 * * *")
    public void customScheduler(){
        try{
            // do what ever you want to run repeatedly
        }catch(Exception e){
            e.printStackTrace();

        }
    }

veuillez également annoter la classe contenant ceci avec l'annotation @Component et fournir @EnableScheduling dans la classe Application.Java (la classe contient la méthode principale) pour que Spring sache que vous utilisez le planificateur de tâches dans votre application.

2
Apurva Singh

utiliser la planification des vides publics (tâche TimerTask, Date firstTime, longue période)

pour que la tâche se répète à nouveau le lendemain, définissez simplement la période sur 86400000 millisecondes (ce qui signifie 1 jour)

Date date2pm = new Java.util.Date();
date2pm.setHour(14);
date2pm.setMinutes(0);

Timer timer = new Timer();

timer.sc(myOwnTimerTask,date2pm, 86400000);
1
Rudy

Échéance Java.util.Timer :

Java 5.0 a introduit le package Java.util.concurrent et l'un des utilitaires de concurrence est le ScheduledThreadPoolExecutor qui est un pool de threads pour exécuter de manière répétée des tâches à un rythme ou un délai donné. Il s'agit en fait d'un remplacement plus polyvalent de la combinaison Timer/TimerTask, car il autorise plusieurs threads de service, accepte diverses unités de temps et ne nécessite pas de sous-classification TimerTask (il suffit d'implémenter Runnable). La configuration de ScheduledThreadPoolExecutor avec un thread le rend équivalent à Timer.

alors (ajoutez ce code à votre classe):

private ScheduledExecutorService scheduledExecutorService;

    public ScheduledSendLog() {
        init();
    }

    public void destroy() {
        this.scheduledExecutorService.shutdown();
    }

    private void init() {
        scheduledExecutorService =
                Executors.newScheduledThreadPool(1);
        System.out.println("---ScheduledSendLog created " + LocalDateTime.now());
        startSchedule(LocalTime.of(02, 00));
    }


    private void startSchedule(LocalTime atTime) {
        this.scheduledExecutorService.scheduleWithFixedDelay(() -> {
                    System.out.println(Thread.currentThread().getName() +
                            " |  scheduleWithFixedDelay | " + LocalDateTime.now());
                    // or whatever you want
                }, calculateInitialDelayInSec(atTime),
                LocalTime.MAX.toSecondOfDay(),
                TimeUnit.SECONDS);
    }

    private long calculateInitialDelayInSec(LocalTime atTime) {
        int currSec = LocalTime.now().toSecondOfDay();
        int atSec = atTime.toSecondOfDay();
        return (currSec < atSec) ?
                atSec - currSec : (LocalTime.MAX.toSecondOfDay() + atSec - currSec);

    }  
1
Alexey Simonov

La plupart des réponses à cette question et aux deux questions suivantes supposent que les millisecondes par jour sont toujours les mêmes .
Comment planifier une tâche périodique en Java?
Comment exécuter certaines tâches chaque jour à une heure particulière en utilisant ScheduledExecutorService?

Cependant, ce n'est pas vrai en raison de l'heure d'été et des secondes intercalaires. Cela signifie que si votre service existe depuis des années et que l'exactitude de la minuterie est importante, une minuterie à période fixe n'est pas votre choix.

Donc, je voudrais présenter mon extrait de code pour un minuteur plus flexible que le 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;
}

Ensuite, vous pouvez exécuter votre travail tous les jours à 14h00 en invoquant la méthode ci-dessus de la manière suivante.

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

    // do your task...

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

L'idée de base derrière le code est de recalculer le temps restant au tick suivant et de démarrer un nouveau temporisateur à chaque fois.

1
Mr. Ree