Class SimpleAsyncTaskScheduler
- All Implemented Interfaces:
Serializable
,AutoCloseable
,Executor
,EventListener
,Aware
,ApplicationContextAware
,ApplicationListener<ContextClosedEvent>
,Lifecycle
,Phased
,SmartLifecycle
,AsyncListenableTaskExecutor
,AsyncTaskExecutor
,TaskExecutor
,TaskScheduler
TaskScheduler
interface, using
a single scheduler thread and executing every scheduled task in an individual
separate thread. This is an attractive choice with virtual threads on JDK 21,
expecting common usage with setVirtualThreads(true)
.
NOTE: Scheduling with a fixed delay enforces execution on a single scheduler thread, in order to provide traditional fixed-delay semantics! Prefer the use of fixed rates or cron triggers instead which are a better fit with this thread-per-task scheduler variant.
Supports a graceful shutdown through SimpleAsyncTaskExecutor.setTaskTerminationTimeout(long)
,
at the expense of task tracking overhead per execution thread at runtime.
Supports limiting concurrent threads through SimpleAsyncTaskExecutor.setConcurrencyLimit(int)
.
By default, the number of concurrent task executions is unlimited.
This allows for dynamic concurrency of scheduled task executions, in contrast
to ThreadPoolTaskScheduler
which requires a fixed pool size.
NOTE: This implementation does not reuse threads! Consider a
thread-pooling TaskScheduler implementation instead, in particular for
scheduling a large number of short-lived tasks. Alternatively, on JDK 21,
consider setting SimpleAsyncTaskExecutor.setVirtualThreads(boolean)
to true
.
Extends SimpleAsyncTaskExecutor
and can serve as a fully capable
replacement for it, for example, as a single shared instance serving as a
TaskExecutor
as well as a TaskScheduler
.
This is generally not the case with other executor/scheduler implementations
which tend to have specific constraints for the scheduler thread pool,
requiring a separate thread pool for general executor purposes in practice.
NOTE: This scheduler variant does not track the actual completion of tasks
but rather just the hand-off to an execution thread. As a consequence,
a ScheduledFuture
handle (for example, from schedule(Runnable, Instant)
)
represents that hand-off rather than the actual completion of the provided task
(or series of repeated tasks). Also, this scheduler participates in lifecycle
management to a limited degree only, stopping trigger firing and fixed-delay
task execution but not stopping the execution of handed-off tasks.
As an alternative to the built-in thread-per-task capability, this scheduler
can also be configured with a separate target executor for scheduled task
execution through setTargetTaskExecutor(java.util.concurrent.Executor)
: for example, pointing to a shared
ThreadPoolTaskExecutor
bean. This is still rather different from a
ThreadPoolTaskScheduler
setup since it always uses a single scheduler
thread while dynamically dispatching to the target thread pool which may have
a dynamic core/max pool size range, participating in a shared concurrency limit.
-
Field Summary
Modifier and TypeFieldDescriptionstatic final int
The default phase for an executorSmartLifecycle
:Integer.MAX_VALUE / 2
.Fields inherited from class org.springframework.core.task.SimpleAsyncTaskExecutor
NO_CONCURRENCY, UNBOUNDED_CONCURRENCY
Fields inherited from interface org.springframework.core.task.AsyncTaskExecutor
TIMEOUT_IMMEDIATE, TIMEOUT_INDEFINITE
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
close()
This close methods tracks the termination of active threads if a concretetask termination timeout
has been set.protected void
Template method for the actual execution of a task.void
Executes the given task, within a concurrency throttle if configured (through the superclass's settings).getClock()
Return the clock to use for scheduling purposes.int
getPhase()
Return the lifecycle phase for pausing and resuming this executor.boolean
Check whether this component is currently running.void
Handle an application event.Schedule the givenRunnable
, invoking it at the specified execution time.Schedule the givenRunnable
, invoking it whenever the trigger indicates a next execution time.scheduleAtFixedRate
(Runnable task, Duration period) Schedule the givenRunnable
, starting as soon as possible and invoking it with the given period.scheduleAtFixedRate
(Runnable task, Instant startTime, Duration period) Schedule the givenRunnable
, invoking it at the specified execution time and subsequently with the given period.scheduleWithFixedDelay
(Runnable task, Duration delay) Schedule the givenRunnable
, starting as soon as possible and invoking it with the given delay between the completion of one execution and the start of the next.scheduleWithFixedDelay
(Runnable task, Instant startTime, Duration delay) Schedule the givenRunnable
, 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.void
setApplicationContext
(ApplicationContext applicationContext) Set the ApplicationContext that this object runs in.void
Set the clock to use for scheduling purposes.void
setErrorHandler
(ErrorHandler errorHandler) Provide anErrorHandler
strategy.void
setPhase
(int phase) Specify the lifecycle phase for pausing and resuming this executor.void
setTargetTaskExecutor
(Executor targetTaskExecutor) Specify a custom targetExecutor
to delegate to for the individual execution of scheduled tasks.void
start()
Start this component.void
stop()
Stop this component, typically in a synchronous fashion, such that the component is fully stopped upon return of this method.void
Indicates that a Lifecycle component must stop if it is currently running.Future<?>
Submit a Runnable task for execution, receiving a Future representing that task.<T> Future<T>
Submit a Callable task for execution, receiving a Future representing that task.submitListenable
(Runnable task) Submit aRunnable
task for execution, receiving aListenableFuture
representing that task.<T> ListenableFuture<T>
submitListenable
(Callable<T> task) Submit aCallable
task for execution, receiving aListenableFuture
representing that task.Methods inherited from class org.springframework.core.task.SimpleAsyncTaskExecutor
execute, getConcurrencyLimit, getThreadFactory, isActive, isThrottleActive, newThread, setConcurrencyLimit, setTaskDecorator, setTaskTerminationTimeout, setThreadFactory, setVirtualThreads
Methods inherited from class org.springframework.util.CustomizableThreadCreator
createThread, getDefaultThreadNamePrefix, getThreadGroup, getThreadNamePrefix, getThreadPriority, isDaemon, nextThreadName, setDaemon, setThreadGroup, setThreadGroupName, setThreadNamePrefix, setThreadPriority
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface org.springframework.context.ApplicationListener
supportsAsyncExecution
Methods inherited from interface org.springframework.core.task.AsyncTaskExecutor
submitCompletable, submitCompletable
Methods inherited from interface org.springframework.context.SmartLifecycle
isAutoStartup
Methods inherited from interface org.springframework.scheduling.TaskScheduler
schedule, scheduleAtFixedRate, scheduleAtFixedRate, scheduleWithFixedDelay, scheduleWithFixedDelay
-
Field Details
-
DEFAULT_PHASE
public static final int DEFAULT_PHASEThe default phase for an executorSmartLifecycle
:Integer.MAX_VALUE / 2
.- Since:
- 6.2
- See Also:
-
-
Constructor Details
-
SimpleAsyncTaskScheduler
public SimpleAsyncTaskScheduler()
-
-
Method Details
-
setErrorHandler
Provide anErrorHandler
strategy.- Since:
- 6.2
-
setClock
Set the clock to use for scheduling purposes.The default clock is the system clock for the default time zone.
- See Also:
-
getClock
Description copied from interface:TaskScheduler
Return the clock to use for scheduling purposes.- Specified by:
getClock
in interfaceTaskScheduler
- See Also:
-
setPhase
public void setPhase(int phase) Specify the lifecycle phase for pausing and resuming this executor. The default isDEFAULT_PHASE
.- See Also:
-
getPhase
public int getPhase()Return the lifecycle phase for pausing and resuming this executor.- Specified by:
getPhase
in interfacePhased
- Specified by:
getPhase
in interfaceSmartLifecycle
- See Also:
-
setTargetTaskExecutor
Specify a custom targetExecutor
to delegate to for the individual execution of scheduled tasks. This can for example be set to a separate thread pool for executing scheduled tasks, whereas this scheduler keeps using its single scheduler thread.If not set, the regular
SimpleAsyncTaskExecutor
arrangements kicks in with a new thread per task. -
setApplicationContext
Description copied from interface:ApplicationContextAware
Set the ApplicationContext that this object runs in. Normally this call will be used to initialize the object.Invoked after population of normal bean properties but before an init callback such as
InitializingBean.afterPropertiesSet()
or a custom init-method. Invoked afterResourceLoaderAware.setResourceLoader(org.springframework.core.io.ResourceLoader)
,ApplicationEventPublisherAware.setApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher)
andMessageSourceAware
, if applicable.- Specified by:
setApplicationContext
in interfaceApplicationContextAware
- Parameters:
applicationContext
- the ApplicationContext object to be used by this object- See Also:
-
doExecute
Description copied from class:SimpleAsyncTaskExecutor
Template method for the actual execution of a task.The default implementation creates a new Thread and starts it.
- Overrides:
doExecute
in classSimpleAsyncTaskExecutor
- Parameters:
task
- the Runnable to execute- See Also:
-
execute
Description copied from class:SimpleAsyncTaskExecutor
Executes the given task, within a concurrency throttle if configured (through the superclass's settings).- Specified by:
execute
in interfaceExecutor
- Specified by:
execute
in interfaceTaskExecutor
- Overrides:
execute
in classSimpleAsyncTaskExecutor
- Parameters:
task
- theRunnable
to execute (nevernull
)- See Also:
-
submit
Description copied from interface:AsyncTaskExecutor
Submit a Runnable task for execution, receiving a Future representing that task. The Future will return anull
result upon completion.As of 6.1, this method comes with a default implementation that delegates to
TaskExecutor.execute(Runnable)
.- Specified by:
submit
in interfaceAsyncTaskExecutor
- Overrides:
submit
in classSimpleAsyncTaskExecutor
- Parameters:
task
- theRunnable
to execute (nevernull
)- Returns:
- a Future representing pending completion of the task
-
submit
Description copied from interface:AsyncTaskExecutor
Submit a Callable task for execution, receiving a Future representing that task. The Future will return the Callable's result upon completion.As of 6.1, this method comes with a default implementation that delegates to
TaskExecutor.execute(Runnable)
.- Specified by:
submit
in interfaceAsyncTaskExecutor
- Overrides:
submit
in classSimpleAsyncTaskExecutor
- Parameters:
task
- theCallable
to execute (nevernull
)- Returns:
- a Future representing pending completion of the task
-
submitListenable
Description copied from interface:AsyncListenableTaskExecutor
Submit aRunnable
task for execution, receiving aListenableFuture
representing that task. The Future will return anull
result upon completion.- Specified by:
submitListenable
in interfaceAsyncListenableTaskExecutor
- Overrides:
submitListenable
in classSimpleAsyncTaskExecutor
- Parameters:
task
- theRunnable
to execute (nevernull
)- Returns:
- a
ListenableFuture
representing pending completion of the task
-
submitListenable
Description copied from interface:AsyncListenableTaskExecutor
Submit aCallable
task for execution, receiving aListenableFuture
representing that task. The Future will return the Callable's result upon completion.- Specified by:
submitListenable
in interfaceAsyncListenableTaskExecutor
- Overrides:
submitListenable
in classSimpleAsyncTaskExecutor
- Parameters:
task
- theCallable
to execute (nevernull
)- Returns:
- a
ListenableFuture
representing pending completion of the task
-
schedule
Description copied from interface:TaskScheduler
Schedule the givenRunnable
, invoking it whenever the trigger indicates a next execution time.Execution will end once the scheduler shuts down or the returned
ScheduledFuture
gets cancelled.- Specified by:
schedule
in interfaceTaskScheduler
- Parameters:
task
- the Runnable to execute whenever the trigger firestrigger
- an implementation of theTrigger
interface, for example, aCronTrigger
object wrapping a cron expression- Returns:
- a
ScheduledFuture
representing pending execution of the task, ornull
if the given Trigger object never fires (i.e. returnsnull
fromTrigger.nextExecution(org.springframework.scheduling.TriggerContext)
) - See Also:
-
schedule
Description copied from interface:TaskScheduler
Schedule the givenRunnable
, invoking it at the specified execution time.Execution will end once the scheduler shuts down or the returned
ScheduledFuture
gets cancelled.- Specified by:
schedule
in interfaceTaskScheduler
- Parameters:
task
- the Runnable to execute whenever the trigger firesstartTime
- the desired execution time for the task (if this is in the past, the task will be executed immediately, i.e. as soon as possible)- Returns:
- a
ScheduledFuture
representing pending execution of the task
-
scheduleAtFixedRate
Description copied from interface:TaskScheduler
Schedule the givenRunnable
, invoking it at the specified execution time and subsequently with the given period.Execution will end once the scheduler shuts down or the returned
ScheduledFuture
gets cancelled.- Specified by:
scheduleAtFixedRate
in interfaceTaskScheduler
- Parameters:
task
- the Runnable to execute whenever the trigger firesstartTime
- the desired first execution time for the task (if this is in the past, the task will be executed immediately, i.e. as soon as possible)period
- the interval between successive executions of the task- Returns:
- a
ScheduledFuture
representing pending execution of the task
-
scheduleAtFixedRate
Description copied from interface:TaskScheduler
Schedule the givenRunnable
, starting as soon as possible and invoking it with the given period.Execution will end once the scheduler shuts down or the returned
ScheduledFuture
gets cancelled.- Specified by:
scheduleAtFixedRate
in interfaceTaskScheduler
- Parameters:
task
- the Runnable to execute whenever the trigger firesperiod
- the interval between successive executions of the task- Returns:
- a
ScheduledFuture
representing pending execution of the task
-
scheduleWithFixedDelay
Description copied from interface:TaskScheduler
Schedule the givenRunnable
, 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.Execution will end once the scheduler shuts down or the returned
ScheduledFuture
gets cancelled.- Specified by:
scheduleWithFixedDelay
in interfaceTaskScheduler
- Parameters:
task
- the Runnable to execute whenever the trigger firesstartTime
- the desired first execution time for the task (if this is in the past, the task will be executed immediately, i.e. as soon as possible)delay
- the delay between the completion of one execution and the start of the next- Returns:
- a
ScheduledFuture
representing pending execution of the task
-
scheduleWithFixedDelay
Description copied from interface:TaskScheduler
Schedule the givenRunnable
, starting as soon as possible and invoking it with the given delay between the completion of one execution and the start of the next.Execution will end once the scheduler shuts down or the returned
ScheduledFuture
gets cancelled.- Specified by:
scheduleWithFixedDelay
in interfaceTaskScheduler
- Parameters:
task
- the Runnable to execute whenever the trigger firesdelay
- the delay between the completion of one execution and the start of the next- Returns:
- a
ScheduledFuture
representing pending execution of the task
-
start
public void start()Description copied from interface:Lifecycle
Start this component.Should not throw an exception if the component is already running.
In the case of a container, this will propagate the start signal to all components that apply.
-
stop
public void stop()Description copied from interface:Lifecycle
Stop this component, typically in a synchronous fashion, such that the component is fully stopped upon return of this method. Consider implementingSmartLifecycle
and itsstop(Runnable)
variant when asynchronous stop behavior is necessary.Note that this stop notification is not guaranteed to come before destruction: On regular shutdown,
Lifecycle
beans will first receive a stop notification before the general destruction callbacks are being propagated; however, on hot refresh during a context's lifetime or on aborted refresh attempts, a given bean's destroy method will be called without any consideration of stop signals upfront.Should not throw an exception if the component is not running (not started yet).
In the case of a container, this will propagate the stop signal to all components that apply.
-
stop
Description copied from interface:SmartLifecycle
Indicates that a Lifecycle component must stop if it is currently running.The provided callback is used by the
LifecycleProcessor
to support an ordered, and potentially concurrent, shutdown of all components having a common shutdown order value. The callback must be executed after theSmartLifecycle
component does indeed stop.The
LifecycleProcessor
will call only this variant of thestop
method; i.e.Lifecycle.stop()
will not be called forSmartLifecycle
implementations unless explicitly delegated to within the implementation of this method.The default implementation delegates to
Lifecycle.stop()
and immediately triggers the given callback in the calling thread. Note that there is no synchronization between the two, so custom implementations may at least want to put the same steps within their common lifecycle monitor (if any).- Specified by:
stop
in interfaceSmartLifecycle
- See Also:
-
isRunning
public boolean isRunning()Description copied from interface:Lifecycle
Check whether this component is currently running.In the case of a container, this will return
true
only if all components that apply are currently running. -
onApplicationEvent
Description copied from interface:ApplicationListener
Handle an application event.- Specified by:
onApplicationEvent
in interfaceApplicationListener<ContextClosedEvent>
- Parameters:
event
- the event to respond to
-
close
public void close()Description copied from class:SimpleAsyncTaskExecutor
This close methods tracks the termination of active threads if a concretetask termination timeout
has been set. Otherwise, it is not necessary to close this executor.- Specified by:
close
in interfaceAutoCloseable
- Overrides:
close
in classSimpleAsyncTaskExecutor
-