ScheduledExecutorService.scheduleAtFixedRate et le réglage initialDelay à ce jour dans le passé

StackOverflow https://stackoverflow.com/questions/3196888

  •  02-10-2019
  •  | 
  •  

Question

Je travaille sur un système de planification en Java qui envoie des rappels en fonction d'un startDate , endDate et occurrence (horaire, quotidien , hebdomadaire, mensuelle, lundi, etc.). Au départ, j'utilisais Minuteur et TimerTask cours pour planifier les rappels:

Timer timer = new Timer();
timer.scheduleAtFixedRate(reminder, firstDate, period);

J'ai récemment passé à ScheduledExecutorService pour que je puisse avoir plus de contrôle sur l'annulation des événements. ScheduledExecutorService fonctionne bien pour les rappels récurrents, sauf pour un cas de rappel rééchelonnements avec startDate dans le passé. scheduleAtFixedRate fonction ne vous permet de spécifier long valeur initialDelay , et non une réelle Date objet:

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(reminder, initialDelay, period, unit);

Cela pose un problème, étant donné que le passage dans un négatif initialDelay provoque toujours l'événement à être déclenché immédiatement causant ainsi à se reproduire à maintenant + période , plutôt que startDate + période .

Toutes les idées comment je peux (re) programmer un rappel avec le startDate dans le passé?

Était-ce utile?

La solution

Il suffit de faire une vérification rapide pour voir si la date est dans le passé, puis créez une nouvelle datetime de départ temporaire est l'incrément du passé de début maintenant.

Autres conseils

Je l'ai résolu en exécutant une fois au démarrage et au moment où je voulais tous les jours:

// check once initial on startup
doSomething();

// and then once every day at midnight utc
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
LocalDateTime firstRun = LocalDate.now(ZoneOffset.UTC).atStartOfDay().plusDays(1);
Duration durationUntilStart = Duration.between(LocalDateTime.now(ZoneOffset.UTC), firstRun);
scheduler.scheduleAtFixedRate(
        () -> doSomething(),
        durationUntilStart.getSeconds() + 1,
        Duration.ofDays(1).getSeconds(),
        TimeUnit.SECONDS
);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top