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 the 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, e.g. 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 (e.g. 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)
: e.g. 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
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
Fields inherited from interface org.springframework.context.SmartLifecycle
DEFAULT_PHASE
-
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.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
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.Methods inherited from class org.springframework.core.task.SimpleAsyncTaskExecutor
execute, execute, getConcurrencyLimit, getThreadFactory, isActive, isThrottleActive, newThread, setConcurrencyLimit, setTaskDecorator, setTaskTerminationTimeout, setThreadFactory, setVirtualThreads, submit, submit, submitListenable, submitListenable
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
-
Constructor Details
-
SimpleAsyncTaskScheduler
public SimpleAsyncTaskScheduler()
-
-
Method Details
-
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 isSmartLifecycle.DEFAULT_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:
-
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, e.g. 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
-