Close

Spring - Task Scheduling Introduction

[Last Updated: Oct 28, 2025]

Task scheduling is the process of creating tasks to run in future time. The task can be for just one time execution or it can be repeated with a specified frequency.



Spring scheduling API is based on TaskScheduler interface.

Definition of TaskScheduler

(Version: spring-framework 6.1.2)
package org.springframework.scheduling;
   ........
public interface TaskScheduler {
    default Clock getClock() {
        return Clock.systemDefaultZone();
    } 1
    @Nullable
    ScheduledFuture<?> schedule(Runnable task, Trigger trigger); 2
    ScheduledFuture<?> schedule(Runnable task, Instant startTime); 3
    @Deprecated(since = "6.0")
    default ScheduledFuture<?> schedule(Runnable task, Date startTime) {
        return schedule(task, startTime.toInstant());
    } 4
    ScheduledFuture<?> scheduleAtFixedRate(
            Runnable task, Instant startTime, Duration period); 5
    @Deprecated(since = "6.0")
    default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period) {
        return scheduleAtFixedRate(task, startTime.toInstant(), Duration.ofMillis(period));
    } 6
    ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Duration period); 7
    @Deprecated(since = "6.0")
    default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) {
        return scheduleAtFixedRate(task, Duration.ofMillis(period));
    } 8
    ScheduledFuture<?> scheduleWithFixedDelay(
            Runnable task, Instant startTime, Duration delay); 9
    @Deprecated(since = "6.0")
    default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
        return scheduleWithFixedDelay(task, startTime.toInstant(), Duration.ofMillis(delay));
    } 10
    ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Duration delay); 11
    @Deprecated(since = "6.0")
    default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay) {
        return scheduleWithFixedDelay(task, Duration.ofMillis(delay));
    } 12
}
1Return the clock to use for scheduling purposes. @since 5.3
2Schedule the given Runnable, invoking it whenever the trigger indicates a next execution time.
3Schedule the given Runnable, invoking it at the specified execution time. @since 5.0
4Schedule the given Runnable, invoking it at the specified execution time.
@deprecated as of 6.0, in favor of #schedule(Runnable, Instant)
5Schedule the given Runnable, invoking it at the specified execution time and subsequently with the given period. @since 5.0
6Schedule the given Runnable, invoking it at the specified execution time and subsequently with the given period.
@deprecated as of 6.0, in favor of #scheduleAtFixedRate(Runnable, Instant, Duration)
7Schedule the given Runnable, starting as soon as possible and invoking it with the given period. @since 5.0
8Schedule the given Runnable, starting as soon as possible and invoking it with the given period.
@deprecated as of 6.0, in favor of #scheduleAtFixedRate(Runnable, Duration)
9Schedule the given Runnable, invoking it at the specified execution time and subsequently with the given delay between the completion of one execution and the start of the next. @since 5.0
10Schedule the given Runnable, invoking it at the specified execution time and subsequently with the given delay between the completion of one execution and the start of the next.
@deprecated as of 6.0, in favor of scheduleWithFixedDelay(Runnable, Instant, Duration)
11Schedule the given Runnable, starting as soon as possible and invoking it with the given delay between the completion of one execution and the start of the next. @since 5.0
12Schedule the given Runnable, starting as soon as possible and invoking it with the given delay between the completion of one execution and the start of the next.
@deprecated as of 6.0, in favor of #scheduleWithFixedDelay(Runnable, Duration)

Above interface looks similar to JSE ScheduledExecutorService. Additionally Spring unifies JSE (JSR-166), JEE (JSR-236) and third party scheduling API into a single TaskScheduler interface.

Trigger interface determines the next execution time based on past execution outcomes or it can be based on any arbitrary conditions.


Definition of Trigger

(Version: spring-framework 6.1.2)
package org.springframework.scheduling;
   ........
public interface Trigger {
    @Deprecated(since = "6.0")
    @Nullable
    default Date nextExecutionTime(TriggerContext triggerContext) {
        Instant instant = nextExecution(triggerContext);
        return (instant != null ? Date.from(instant) : null);
    } 1
    @Nullable
    Instant nextExecution(TriggerContext triggerContext); 2
}
1Determine the next execution time according to the given trigger context.
@deprecated as of 6.0, in favor of #nextExecution(TriggerContext)
2Determine the next execution time according to the given trigger context

Definition of TriggerContext

(Version: spring-framework 6.1.2)
package org.springframework.scheduling;
   ........
public interface TriggerContext {
    default Clock getClock() {
        return Clock.systemDefaultZone();
    } 1
    @Nullable
    @Deprecated(since = "6.0")
    default Date lastScheduledExecutionTime() {
        Instant instant = lastScheduledExecution();
        return (instant != null ? Date.from(instant) : null);
    } 2
    @Nullable
    Instant lastScheduledExecution(); 3
    @Nullable
    @Deprecated(since = "6.0")
    default Date lastActualExecutionTime() {
        Instant instant = lastActualExecution();
        return (instant != null ? Date.from(instant) : null);
    } 4
    @Nullable
    Instant lastActualExecution(); 5
    @Deprecated(since = "6.0")
    @Nullable
    default Date lastCompletionTime() {
        Instant instant = lastCompletion();
        return (instant != null ? Date.from(instant) : null);
    } 6
    @Nullable
    Instant lastCompletion(); 7
}
1Return the clock to use for trigger calculation. @since 5.3
2Return the last scheduled execution time of the task, or null if not scheduled before.
@deprecated as of 6.0, in favor on #lastScheduledExecution()
3Return the last scheduled execution time of the task, or null if not scheduled before. @since 6.0
4Return the last actual execution time of the task, or null if not scheduled before.
@deprecated as of 6.0, in favor on #lastActualExecution()
5Return the last actual execution time of the task, or null if not scheduled before. @since 6.0
6Return the last completion time of the task, or null if not scheduled before.
@deprecated as of 6.0, in favor on #lastCompletion()
7 Return the last completion time of the task, or null if not scheduled before. @since 6.0

Normally we shouldn't worry about implementing Trigger and TriggerContext interfaces, as Spring provides some implementations to fulfill our needs.



TaskScheduler implementations

  • SimpleAsyncTaskScheduler

    A simple implementation of Spring's TaskScheduler interface, using a single scheduler thread and executing every scheduled task in an individual separate thread.

  • ThreadPoolTaskScheduler

    A standard implementation of Spring's TaskScheduler interface, wrapping a native ScheduledThreadPoolExecutor and providing all applicable configuration options for it.

  • ConcurrentTaskScheduler

    Adapter that takes a java.util.concurrent.ScheduledExecutorService and exposes a Spring TaskScheduler for it. Extends ConcurrentTaskExecutor in order to implement the SchedulingTaskExecutor interface as well.

  • DefaultManagedTaskScheduler

    JNDI-based variant of ConcurrentTaskScheduler

  • TaskSchedulerRouter

    A routing implementation of the TaskScheduler interface, delegating to a target scheduler based on an identified qualifier or using a default scheduler otherwise. @since 6.1


Trigger implementation

  • PeriodicTrigger

    A trigger for periodic task execution.

  • CronTrigger

    Trigger implementation for cron expressions. Wraps a CronExpression.

In next tutorials we will see the example of each implementations.


See Also