Spring Top

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:


1. Overview

In this article, we'll discuss the Spring task scheduling mechanismsTaskScheduler and it's pre-built implementations along with the different triggers to use. If you want to read more about scheduling in Spring, check @Async and @Scheduled articles.

TaskScheduler was introduced in Spring 3.0 with a variety of methods to run at some point in the future, it also returns a representation object of ScheduledFuture interface, which could be used to cancel scheduled task or check if it's done or not.

All we need to do is to select a runnable task for scheduling then select a proper scheduling policy.

2. ThreadPoolTaskScheduler

ThreadPoolTaskScheduler is well suited for internal thread management, as it delegates tasks to the ScheduledExecutorService and implements the TaskExecutor interface – so that single instance of it is able to handle asynchronous potential executions as well as the @Scheduled annotation.

Let's now define ThreadPoolTaskScheduler bean at ThreadPoolTaskSchedulerConfig:

public class ThreadPoolTaskSchedulerConfig {

    public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
        ThreadPoolTaskScheduler threadPoolTaskScheduler
          = new ThreadPoolTaskScheduler();
        return threadPoolTaskScheduler;

The configured bean threadPoolTaskScheduler can execute tasks asynchronously based on the configured pool size of 5.

Note that all ThreadPoolTaskScheduler related thread names will be prefixed with ThreadPoolTaskScheduler.

Let's implement a simple task we can then schedule:

class RunnableTask implements Runnable{
    private String message;
    public RunnableTask(String message){
        this.message = message;
    public void run() {
        System.out.println(new Date()+" Runnable Task with "+message
          +" on thread "+Thread.currentThread().getName());

We can now simple schedule this task to be executed by the scheduler:

  new Runnabletask("Specific time, 3 Seconds from now"),
  new Date(System.currentTimeMillis + 3000)

The taskScheduler will schedule this runnable task at a known date, exactly 3 seconds after the current time.

Let's now go a bit more in-depth with the ThreadPoolTaskScheduler scheduling mechanisms.

3. Schedule Runnable Task With Fixed Delay

Scheduling with a fixed delay can be done with two simple mechanisms:

3.1. Scheduling After a Fixed Delay of the Last Scheduled Execution

Let’s configure a task to run after a fixed delay of 1000 milliseconds:

  new RunnableTask("Fixed 1 second Delay"), 1000);

The RunnableTask will always run 1000 milliseconds later between the completion of one execution and the start of the next.

3.2. Scheduling After a Fixed Delay of a Specific Date

Let's configure a task to run after a fixed delay of a given start time:

  new RunnableTask("Current Date Fixed 1 second Delay"),
  new Date(),

The RunnableTask will be invoked at the specified execution time which mainly the time in which @PostConstruct method starts and subsequently with 1000 milliseconds delay.

4. Scheduling at a Fixed Rate

There are two simple mechanisms for scheduling runnable tasks at fixed rate:

4.1. Scheduling the RunnableTask at a Fixed Rate

Let's schedule a task to run at a fixed rate of milliseconds:

  new RunnableTask("Fixed Rate of 2 seconds") , 2000);

The next RunnableTask will run always after 2000 milliseconds no matter the status of last execution which may be still running.

4.2. Scheduling the RunnableTask at a Fixed Rate From a Given Date

taskScheduler.scheduleAtFixedRate(new RunnableTask(
  "Fixed Rate of 2 seconds"), new Date(), 3000);

The RunnableTask will run 3000 milliseconds after the current time.

5. Scheduling with CronTrigger

CronTrigger is used to schedule a task based on a cron expression:

CronTrigger cronTrigger 
  = new CronTrigger("10 * * * * ?");

The provided trigger can be used to run a task according to a certain specified cadence or schedule:

taskScheduler.schedule(new RunnableTask("Cron Trigger"), cronTrigger);

In this case, the RunnableTask will be executed at the 10th second of every minute.

6. Scheduling with PeriodicTrigger

Let's use PeriodicTrigger for scheduling a task with a fixed delay of 2000 milliseconds:

PeriodicTrigger periodicTrigger 
  = new PeriodicTrigger(2000, TimeUnit.MICROSECONDS);

The configured PeriodicTrigger bean would be used to run a task after a fixed delay of 2000 millisecond.

Now let's schedule the RunnableTask with the PeriodicTrigger:

  new RunnableTask("Periodic Trigger"), periodicTrigger);

We also can configure PeriodicTrigger to be initialized at a fixed rate rather than fixed delay, also we can set an initial delay for the first scheduled task by a given milliseconds.

All we need to do is to add two lines of code before return statement at the periodicTrigger bean:


We used the setFixedRate method to schedule the task at fixed rate rather than with a fixed delay, then setInitialDelay method is used to set initial delay only for the first runnable task to run.

7. Conclusion

In this quick article, we've illustrated how to schedule a runnable task using the Spring support for tasks.

We looked at running the task with a fixed delay, at a fixed rate and according to a specified trigger.

And, as always, the code is available as a Maven project over in GitHub.

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

Generic footer banner
1 Comment
Inline Feedbacks
View all comments
Comments are closed on this article!