A Guide to the Spring Task Scheduler

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.

TaskScheuler 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:_
_

@Configuration
@ComponentScan(
  basePackages="org.baeldung.taskscheduler",
  basePackageClasses={ThreadPoolTaskSchedulerExamples.class})
public class ThreadPoolTaskSchedulerConfig {

    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
        ThreadPoolTaskScheduler threadPoolTaskScheduler
          = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.setPoolSize(5);
        threadPoolTaskScheduler.setThreadNamePrefix(
          "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;
    }

    @Override
    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:

taskScheduler.schedule(
  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

[[scheduling-after-a-fixed-delay-of—​the-last-scheduled-execution]]Let’s configure a task to run after a fixed delay of 1000 milliseconds:

taskScheduler.scheduleWithFixedDelay(
  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:

taskScheduler.scheduleWithFixedDelay(
  new RunnableTask("Current Date Fixed 1 second Delay"),
  new Date(),
  1000);

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:

taskScheduler.scheduleAtFixedRate(
  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

[source,java,gutter:,true]

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:

taskScheduler.schedule(
  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:

periodicTrigger.setFixedRate(true);
periodicTrigger.setInitialDelay(1000);

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.

Leave a Reply

Your email address will not be published.