scheduleAtFixedRate vs scheduleWithFixedDelay

JavaScheduled TasksScheduledexecutorservice

Java Problem Overview


What's the main difference between scheduleAtFixedRate and scheduleWithFixedDelay methods of 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);

they print exact the same time, seems they are executed at exact the same interval.

Java Solutions


Solution 1 - Java

Try adding a Thread.sleep(1000); call within your run() method... Basically it's the difference between scheduling something based on when the previous execution ends and when it (logically) starts.

For example, suppose I schedule an alarm to go off with a fixed rate of once an hour, and every time it goes off, I have a cup of coffee, which takes 10 minutes. Suppose that starts at midnight, I'd have:

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

If I schedule with a fixed delay of one hour, I'd have:

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

Which one you want depends on your task.

Solution 2 - Java

Visualize time series of invocation scheduleAtFixedRate method. Next executions will start immediately if the last one takes longer than period. Otherwise, it will start after period time.

time series of invocation scheduleAtFixedRate method

Time series of invocation scheduleWithFixedDelay method. Next execution will start after delay time between termination of one execution and the commencement of the next, regardless of its execution time

time series of invocation scheduleWithFixedDelay method

Hope can help you

Solution 3 - Java

The scheduleAtFixedRate() method creates a new task and submits it to the executor every period, regardless of whether or not the previous task finished.

On the other hand, the scheduleWithFixedDelay() method creates a new task after the previous task has finished.

Solution 4 - Java

If you read the Java Doc it will be clearer

ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on.

ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next.

Solution 5 - Java

There is one catch in scheduleAtFixedRate if first thread is taking too long and not ended in given duration then second conscutive thread will not start once the first task will get finsished and will not imediately get started while the first thread has comepleted their task and gievn duration has been elapsed. JVM Will decide when the next task will get executed .

I think that will help you to choose method Becuase due to this i got big problem

Solution 6 - Java

Let's write a simple program:

import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit

var time = 0L
var start = System.currentTimeMillis()
val executor = Executors.newScheduledThreadPool(1)
executor.scheduleWithFixedDelay({
    if (time >= 12_000L) {
        executor.shutdown()
    } else {
        Thread.sleep(2000L)
        val now = System.currentTimeMillis()
        time += now - start
        System.out.println("Total $time delay ${now - start}\n")
        start = now
    }
}, 0L, 1000L, TimeUnit.MILLISECONDS)

And see the results:

| scheduleWithFixedDelay |   scheduleAtFixedRate  |
|:----------------------:|:----------------------:|
| Total 2001 delay 2001  | Total 2003 delay 2003  |
| Total 5002 delay 3001  | Total 4004 delay 2001  |
| Total 8003 delay 3001  | Total 6004 delay 2000  |
| Total 11003 delay 3000 | Total 8004 delay 2000  |
| Total 14003 delay 3000 | Total 10005 delay 2001 |
|          ---           | Total 12005 delay 2000 |

NOTICE the execution time is bigger than waiting

scheduleWithFixedDelay keeps delay
scheduleAtFixedRate removes delay

Solution 7 - Java

I can see your premiss but your conclusion is not quite right. Here is a good and quite complete explanation according to this Tutorial for understanding the diferences bitween these two.

scheduleAtFixedRate (Runnable, long initialDelay, long period, TimeUnit timeunit)

This method schedules a task to be executed periodically. The task is executed the first time after the initialDelay, and then recurringly every time the period expires. If any execution of the given task throws an exception, the task is no longer executed. If no exceptions are thrown, the task will continue to be executed until the ScheduledExecutorService is shut down. If a task takes longer to execute than the period between its scheduled executions, the next execution will start after the current execution finishes. The scheduled task will not be executed by more than one thread at a time.

scheduleWithFixedDelay (Runnable, long initialDelay, long period, TimeUnit timeunit)

This method works very much like scheduleAtFixedRate() except that the period is interpreted differently. In the scheduleAtFixedRate() method the period is interpreted as a delay between the start of the previous execution, until the start of the next execution. In this method, however, the period is interpreted as the delay between the end of the previous execution, until the start of the next. The delay is thus between finished executions, not between the beginning of executions.

Solution 8 - Java

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

Just execute it, and you will know the difference. Thank you

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSawyerView Question on Stackoverflow
Solution 1 - JavaJon SkeetView Answer on Stackoverflow
Solution 2 - JavaKen BlockView Answer on Stackoverflow
Solution 3 - JavaImarView Answer on Stackoverflow
Solution 4 - JavashazinView Answer on Stackoverflow
Solution 5 - Javauser1047873View Answer on Stackoverflow
Solution 6 - JavaVladView Answer on Stackoverflow
Solution 7 - JavaStackOverflowerView Answer on Stackoverflow
Solution 8 - Javalogi techView Answer on Stackoverflow