ScheduleAtFixedRate vs scheduleWithFixedDelay

В чем основное отличие методов scheduleAtFixedRate и scheduleWithFixedDelay от 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);

они печатают точно одно и то же время, кажется, что они выполняются с точным одним и тем же интервалом.

Ответ 1

Попробуйте добавить вызов Thread.sleep(1000); в свой метод run()... В основном это различие между планированием чего-то, основанным на завершении предыдущего выполнения и при его (логическом) запуске.

Например, предположим, что я планирую, чтобы будильник погас с фиксированной скоростью один раз в час, и каждый раз, когда он гаснет, у меня есть чашка кофе, которая занимает 10 минут. Предположим, что в полночь у меня будет:

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

Если я планирую с фиксированной задержкой в ​​один час, у меня будет:

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

Какой из них вы хотите, зависит от вашей задачи.

Ответ 2

Визуализируйте временные ряды метода вызова scheduleAtFixedRate. Следующие казни начнутся немедленно, если последний займет больше времени, чем период. В противном случае он начнется после периода времени.

time series of invocation scheduleAtFixedRate method

Временной ряд метода вызова scheduleWithFixedDelay. Следующее выполнение начнется после времени задержки между завершением одного выполнения и началом следующего, независимо от времени его выполнения

time series of invocation scheduleWithFixedDelay method

Надежда может помочь вам

Ответ 3

Метод scheduleAtFixedRate() создает новую задачу и отправляет ее исполнителю каждый период, независимо от того, завершила ли предыдущая задача.

С другой стороны, метод scheduleAtFixedDelay() создает новую задачу после завершения предыдущей задачи.

Ответ 4

Если вы прочитаете Java Doc, он станет более понятным

ScheduledFuture scheduleAtFixedRate (Runnable command, long initialDelay, long period, TimeUnit unit) Создает и выполняет периодическое действие, которое активируется сначала после заданной начальной задержки, а затем с заданным периодом; то есть выполнение будет начато после initialDelay, затем initialDelay + period, затем initialDelay + 2 * period и т.д.

ScheduledFuture scheduleWithFixedDelay (Runnable command, long initialDelay, long delay, TimeUnit unit) Создает и выполняет периодическое действие, которое активируется сначала после заданной начальной задержки, а затем с указанной задержкой между завершением одного выполнения и началом следующего.

Ответ 5

Есть один catch в scheduleAtFixedRate, если первый поток занимает слишком много времени и не заканчивается в заданной продолжительности, тогда второй conscutive thread не запускается после того, как первая задача будет обработана и не будет сразу запускаться, пока первый поток исчерпал свою задачу и длительность gievn. JVM примет решение о выполнении следующей задачи.

Я думаю, что это поможет вам выбрать метод Becuase из-за этого у меня возникла большая проблема

Ответ 6

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);

Просто выполните его, и вы поймете разницу. Спасибо