SpringBoot scheduled tasks or methods using @Scheduled.

FixedRate / FixedRateString

We can schedule a method in SpringBoot very easily using the @Scheduled annotation. A very simple scheduler which prints the current date-time every 1 second is provided below.

@Component
@EnableScheduling
public class SampleScheduler {

   @Scheduled(fixedRate = 1000)
   public void printCurrentDateTime(){
       System.out.println(LocalDateTime.now());
   }
}

Note: You have to add @EnableScheduling annotation at the class level. Else the method will not be scheduled.

Output of the above method is provided below.

2021-07-07 23:45:32.811 INFO 12608 --- [ main] c.j.schedule.ScheduleApplication : No active profile set, falling back to default profiles: default
2021-07-07T23:45:33.864565900
2021-07-07 23:45:33.872 INFO 12608 --- [ main] c.j.schedule.ScheduleApplication : Started ScheduleApplication in 1.911 seconds (JVM running for 2.635)
2021-07-07T23:45:34.874786500
2021-07-07T23:45:35.873880300
2021-07-07T23:45:36.867551300
2021-07-07T23:45:37.863919700

To get the value from application.properties or application.yml @Scheduled annotation has corresponding String properties. (example: fixedRateString)

The below example schedules the method every 5 seconds.

## application.properties

scheduler.fixed-rate=5000
@Component
@EnableScheduling
public class SampleScheduler {

    @Scheduled(fixedRateString = "${scheduler.fixed-rate}")
    public void printCurrentDateTime(){
        System.out.println(LocalDateTime.now());
    }
}

All the available properties or fields of @Scheduled annotation are provided below.

Optional ElementsDescription
cronA cron-like expression, extending the usual UN*X definition to include triggers on the second, minute, hour, day of month, month, and day of week.
fixedDelay / fixedDelayStringExecute the annotated method with a fixed period in milliseconds between the end of the last invocation and the start of the next.
fixedRate / fixedRateStringExecute the annotated method with a fixed period in milliseconds between invocations.
initialDelay / initialDelayStringNumber of milliseconds to delay before the first execution of a fixedRate() or fixedDelay() task.
zoneA time zone for which the cron expression will be resolved.

initialDelay & fixedDelay.

The below example waits 5 seconds for the first execution and then executes the method every 3 seconds.

@Component
@EnableScheduling
public class SampleScheduler {

   @Scheduled(initialDelay = 5000, fixedDelay = 3000)
   public void printCurrentDateTime(){
       System.out.println(LocalDateTime.now());
   }

    @Scheduled(initialDelayString =  "${scheduler.initial-delay}", fixedDelayString = "${scheduler.fixed-delay}")
    public void printCurrentDateTimeString(){
        System.out.println(LocalDateTime.now());
    }
}
# application.properties

scheduler.initial-delay=5000
scheduler.fixed-delay=3000

cron

The below code executes the method every 2nd minute from 0 through 59.

@Component
@EnableScheduling
public class SampleScheduler {

    @Scheduled(cron = "0 0/2 * * * *")
    public void printCurrentDateTime(){
        System.out.println(LocalDateTime.now());
    }

    @Scheduled(cron = "${scheduler.cron}")
    public void printCurrentDateTimeExternalProperty(){
        System.out.println(LocalDateTime.now());
    }
}
# application.properties

scheduler.cron= 0 0/2 * * * *

Note: If we schedule two methods at the same time, one method will wait for the FIRST one to complete before scheduling.

For example consider the below 2 methods: They both are scheduled to run every 2nd minute. But if method1 starts first then method 2 will wait till method1 is completed.

@Scheduled(cron = "0 0/2 * * * *")
public void method1(){
// do something
}

@Scheduled(cron = "0 0/2 * * * *")
public void method2(){
// do something
}

If we want the second method to run simultaneously with the first method as per the cron expression we need to add @Async to both the methods. We should also add @EnableAsync at the class level as shown below.

@Component
@EnableScheduling
@EnableAsync
public class SampleScheduler {

  @Async
  @Scheduled(cron = "0 0/2 * * * *")
  public void method1(){
    // do something
  }

  @Async
  @Scheduled(cron = "0 0/2 * * * *")
  public void method2(){
    // do something
  }

}

%d bloggers like this: