web-dev-qa-db-fra.com

scheduleAtFixedRate vs scheduleWithFixedDelay

Quelle est la principale différence entre scheduleAtFixedRate et scheduleWithFixedDelay méthodes de ScheduledExecutorService ?

scheduler.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        System.out.println("scheduleAtFixedRate:    " + new Date());
    }
}, 1, 3L , SECONDS);

scheduler.scheduleWithFixedDelay(new Runnable() {
    @Override
    public void run() {
        System.out.println("scheduleWithFixedDelay: " + new Date());
    }
}, 1, 3L , SECONDS);

ils impriment exactement en même temps, ils semblent être exécutés exactement au même intervalle.

97
Sawyer

Essayez d’ajouter un appel Thread.sleep(1000); dans votre méthode run() ... Fondamentalement, c’est la différence entre planifier quelque chose en fonction du moment où la précédente exécution fin et quand (logiquement ) commence.

Par exemple, supposons que je planifie une alarme pour déclencher avec un taux d'une fois par heure et que, chaque fois que cela se déclenche, je prends une tasse de café, ce qui prend 10 minutes. Supposons que cela commence à minuit, j'aurais:

00:00: Start making coffee
00:10: Finish making coffee
01:00: Start making coffee
01:10: Finish making coffee
02:00: Start making coffee
02:10: Finish making coffee

Si je programme avec un retard fixe d'une heure, j'aurais:

00:00: Start making coffee
00:10: Finish making coffee
01:10: Start making coffee
01:20: Finish making coffee
02:20: Start making coffee
02:30: Finish making coffee

Lequel vous voulez dépend de votre tâche.

168
Jon Skeet

Visualisez la série chronologique de la méthode d'invocation scheduleAtFixedRate. Les prochaines exécutions commenceront immédiatement si la dernière prend plus de temps. Sinon, il commencera après la période.

time series of invocation scheduleAtFixedRate method

Série chronologique d'invocation scheduleWithFixedDelay méthode. La prochaine exécution commencera après le délai entre la fin d'une exécution et le début de la suivante, quelle que soit sa durée d'exécution

time series of invocation scheduleWithFixedDelay method

L'espoir peut vous aider

48
Ken Block

La méthode scheduleAtFixedRate () crée une nouvelle tâche et la soumet à l'exécuteur à chaque période, que la tâche précédente ait été terminée ou non.

D'autre part, la méthode scheduleAtFixedDelay () crée une nouvelle tâche ne fois la tâche précédente terminée.

2
Imar

Si vous lisez le Java Doc, ce sera plus clair

ScheduledFuture scheduleAtFixedRate (commande exécutable, long initialDelay, long period, unité TimeUnit) crée et exécute une action périodique qui est activée en premier après le délai initial indiqué, puis ultérieurement avec la période donnée; c'est-à-dire que les exécutions commenceront après initialDelay, puis initialDelay + period, puis initialDelay + 2 * period, et ainsi de suite.

ScheduledFuture scheduleWithFixedDelay (commande exécutable, long initialDelay, long delay, unité TimeUnit) Crée et exécute une action périodique qui est activée en premier après le délai initial indiqué, puis avec le délai spécifié entre la fin d'une exécution et le commencement du prochain.

1
shazin

ScheduleAtFixedRate présente un problème si le premier thread prend trop de temps et qu'il n'est pas terminé dans un délai donné, le second thread conscient ne démarrera pas une fois que la première tâche sera terminée et ne démarrera pas immédiatement tant que le premier thread aura été exécuté et la durée écoulée. a été écoulé. JVM décidera quand la prochaine tâche sera exécutée.

Je pense que cela vous aidera à choisir la méthode Becuase pour cette raison que j'ai un gros problème

1
user1047873
scheduledExecutorService.scheduleAtFixedRate(() -> {
        System.out.println("runnable start"); try { Thread.sleep(5000);  System.out.println("runnable end");} catch
     (InterruptedException e) { // TODO Auto-generated catch block
      e.printStackTrace(); }}, 2, 7, TimeUnit.SECONDS);



     scheduledExecutorService.scheduleWithFixedDelay(() -> {
     System.out.println("runnable start"); try { Thread.sleep(5000); System.out.println("runnable end");} catch
     (InterruptedException e) { // TODO Auto-generated catch block
     e.printStackTrace(); } }, 2, 7, TimeUnit.SECONDS);

Il suffit de l'exécuter, et vous saurez la différence. Je vous remercie

0
logi tech