Core starter providing fundamental building blocks for Spring Boot applications with auto-configuration support, logging, and YAML parsing
—
Asynchronous task execution and scheduling infrastructure with customizable thread pool management.
Builders for creating and configuring various types of task executors.
/**
* Builder that can be used to configure and create a ThreadPoolTaskExecutor
*/
public class ThreadPoolTaskExecutorBuilder {
/**
* Create a new ThreadPoolTaskExecutorBuilder instance
*/
public ThreadPoolTaskExecutorBuilder();
/**
* Set the core number of threads
* @param corePoolSize the core pool size
* @return a new builder instance
*/
public ThreadPoolTaskExecutorBuilder corePoolSize(int corePoolSize);
/**
* Set the maximum allowed number of threads
* @param maxPoolSize the maximum pool size
* @return a new builder instance
*/
public ThreadPoolTaskExecutorBuilder maxPoolSize(int maxPoolSize);
/**
* Set the queue capacity for the ThreadPoolExecutor
* @param queueCapacity the queue capacity
* @return a new builder instance
*/
public ThreadPoolTaskExecutorBuilder queueCapacity(int queueCapacity);
/**
* Set the time limit for which threads may remain idle before being terminated
* @param keepAlive the keep alive duration
* @return a new builder instance
*/
public ThreadPoolTaskExecutorBuilder keepAlive(Duration keepAlive);
/**
* Set whether to allow core threads to time out
* @param allowCoreThreadTimeOut whether to allow core thread time out
* @return a new builder instance
*/
public ThreadPoolTaskExecutorBuilder allowCoreThreadTimeOut(boolean allowCoreThreadTimeOut);
/**
* Set the prefix to use for the names of newly created threads
* @param threadNamePrefix the thread name prefix
* @return a new builder instance
*/
public ThreadPoolTaskExecutorBuilder threadNamePrefix(String threadNamePrefix);
/**
* Set the RejectedExecutionHandler to use for the ExecutorService
* @param rejectedExecutionHandler the rejected execution handler
* @return a new builder instance
*/
public ThreadPoolTaskExecutorBuilder rejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler);
/**
* Set whether the executor should wait for scheduled tasks to complete on shutdown
* @param waitForTasksToCompleteOnShutdown whether to wait for tasks to complete on shutdown
* @return a new builder instance
*/
public ThreadPoolTaskExecutorBuilder waitForTasksToCompleteOnShutdown(boolean waitForTasksToCompleteOnShutdown);
/**
* Set the maximum time the executor is supposed to block on shutdown
* @param awaitTerminationMillis the await termination period
* @return a new builder instance
*/
public ThreadPoolTaskExecutorBuilder awaitTerminationMillis(long awaitTerminationMillis);
/**
* Add customizers that should be applied to the ThreadPoolTaskExecutor
* @param customizers the customizers to add
* @return a new builder instance
*/
public ThreadPoolTaskExecutorBuilder customizers(ThreadPoolTaskExecutorCustomizer... customizers);
/**
* Build a new ThreadPoolTaskExecutor instance and configure it using this builder
* @return a configured ThreadPoolTaskExecutor instance
*/
public ThreadPoolTaskExecutor build();
}
/**
* Builder that can be used to configure and create a SimpleAsyncTaskExecutor
*/
public class SimpleAsyncTaskExecutorBuilder {
/**
* Create a new SimpleAsyncTaskExecutorBuilder instance
*/
public SimpleAsyncTaskExecutorBuilder();
/**
* Set the prefix to use for the names of newly created threads
* @param threadNamePrefix the thread name prefix
* @return a new builder instance
*/
public SimpleAsyncTaskExecutorBuilder threadNamePrefix(String threadNamePrefix);
/**
* Set the maximum number of allowed concurrent tasks
* @param concurrencyLimit the concurrency limit
* @return a new builder instance
*/
public SimpleAsyncTaskExecutorBuilder concurrencyLimit(int concurrencyLimit);
/**
* Set the virtual thread name prefix to use
* @param virtualThreadNamePrefix the virtual thread name prefix
* @return a new builder instance
*/
public SimpleAsyncTaskExecutorBuilder virtualThreadNamePrefix(String virtualThreadNamePrefix);
/**
* Set the TaskDecorator to apply to any Runnable about to be executed
* @param taskDecorator the task decorator
* @return a new builder instance
*/
public SimpleAsyncTaskExecutorBuilder taskDecorator(TaskDecorator taskDecorator);
/**
* Add customizers that should be applied to the SimpleAsyncTaskExecutor
* @param customizers the customizers to add
* @return a new builder instance
*/
public SimpleAsyncTaskExecutorBuilder customizers(SimpleAsyncTaskExecutorCustomizer... customizers);
/**
* Build a new SimpleAsyncTaskExecutor instance and configure it using this builder
* @return a configured SimpleAsyncTaskExecutor instance
*/
public SimpleAsyncTaskExecutor build();
}
/**
* Builder that can be used to configure and create a ThreadPoolTaskScheduler
*/
public class ThreadPoolTaskSchedulerBuilder {
/**
* Create a new ThreadPoolTaskSchedulerBuilder instance
*/
public ThreadPoolTaskSchedulerBuilder();
/**
* Set the scheduler's pool size
* @param poolSize the pool size
* @return a new builder instance
*/
public ThreadPoolTaskSchedulerBuilder poolSize(int poolSize);
/**
* Set the time limit for which threads may remain idle before being terminated
* @param keepAlive the keep alive duration
* @return a new builder instance
*/
public ThreadPoolTaskSchedulerBuilder keepAlive(Duration keepAlive);
/**
* Set the prefix to use for the names of newly created threads
* @param threadNamePrefix the thread name prefix
* @return a new builder instance
*/
public ThreadPoolTaskSchedulerBuilder threadNamePrefix(String threadNamePrefix);
/**
* Set the RejectedExecutionHandler to use for the ExecutorService
* @param rejectedExecutionHandler the rejected execution handler
* @return a new builder instance
*/
public ThreadPoolTaskSchedulerBuilder rejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler);
/**
* Set whether the executor should wait for scheduled tasks to complete on shutdown
* @param waitForTasksToCompleteOnShutdown whether to wait for tasks to complete on shutdown
* @return a new builder instance
*/
public ThreadPoolTaskSchedulerBuilder waitForTasksToCompleteOnShutdown(boolean waitForTasksToCompleteOnShutdown);
/**
* Set the maximum time the executor is supposed to block on shutdown
* @param awaitTerminationMillis the await termination period
* @return a new builder instance
*/
public ThreadPoolTaskSchedulerBuilder awaitTerminationMillis(long awaitTerminationMillis);
/**
* Add customizers that should be applied to the ThreadPoolTaskScheduler
* @param customizers the customizers to add
* @return a new builder instance
*/
public ThreadPoolTaskSchedulerBuilder customizers(ThreadPoolTaskSchedulerCustomizer... customizers);
/**
* Build a new ThreadPoolTaskScheduler instance and configure it using this builder
* @return a configured ThreadPoolTaskScheduler instance
*/
public ThreadPoolTaskScheduler build();
}Customizer interfaces for fine-tuning task executor behavior.
/**
* Callback interface that can be used to customize a ThreadPoolTaskExecutor
*/
@FunctionalInterface
public interface ThreadPoolTaskExecutorCustomizer {
/**
* Callback to customize a ThreadPoolTaskExecutor instance
* @param taskExecutor the task executor to customize
*/
void customize(ThreadPoolTaskExecutor taskExecutor);
}
/**
* Callback interface that can be used to customize a SimpleAsyncTaskExecutor
*/
@FunctionalInterface
public interface SimpleAsyncTaskExecutorCustomizer {
/**
* Callback to customize a SimpleAsyncTaskExecutor instance
* @param taskExecutor the task executor to customize
*/
void customize(SimpleAsyncTaskExecutor taskExecutor);
}
/**
* Callback interface that can be used to customize a ThreadPoolTaskScheduler
*/
@FunctionalInterface
public interface ThreadPoolTaskSchedulerCustomizer {
/**
* Callback to customize a ThreadPoolTaskScheduler instance
* @param taskScheduler the task scheduler to customize
*/
void customize(ThreadPoolTaskScheduler taskScheduler);
}Core interfaces for task execution and decoration.
/**
* Simple task executor interface that abstracts the execution of a Runnable
*/
@FunctionalInterface
public interface TaskExecutor extends Executor {
/**
* Execute the given task
* @param task the Runnable to execute (never null)
*/
@Override
void execute(Runnable task);
}
/**
* A TaskExecutor extension exposing scheduling characteristics that are relevant to potential task submitters
*/
public interface AsyncTaskExecutor extends TaskExecutor {
/**
* Constant that indicates immediate execution
*/
long TIMEOUT_IMMEDIATE = 0;
/**
* Constant that indicates no time limit
*/
long TIMEOUT_INDEFINITE = Long.MAX_VALUE;
/**
* Execute the given task asynchronously
* @param task the Runnable to execute (never null)
* @param startTimeout the time duration within which the task is supposed to start
*/
void execute(Runnable task, long startTimeout);
/**
* Submit a Runnable task for execution, receiving a Future representing that task
* @param task the Runnable to submit
* @return a Future representing pending completion of the task
*/
Future<?> submit(Runnable task);
/**
* Submit a Callable task for execution, receiving a Future representing that task
* @param task the Callable to submit
* @return a Future representing pending completion of the task
*/
<T> Future<T> submit(Callable<T> task);
}
/**
* Strategy interface for decorating a Runnable about to be executed
*/
@FunctionalInterface
public interface TaskDecorator {
/**
* Decorate the given Runnable, returning a potentially wrapped Runnable for actual execution
* @param runnable the original Runnable
* @return the decorated Runnable
*/
Runnable decorate(Runnable runnable);
}Support for scheduled task execution with cron expressions and fixed delays.
/**
* Task scheduling interface that abstracts the scheduling of Runnables based on different kinds of triggers
*/
public interface TaskScheduler {
/**
* Schedule the given Runnable, invoking it whenever the trigger indicates a next execution time
* @param task the Runnable to execute whenever the trigger fires
* @param trigger an implementation of the Trigger interface
* @return a ScheduledFuture representing pending completion of the task
*/
ScheduledFuture<?> schedule(Runnable task, Trigger trigger);
/**
* Schedule the given Runnable, invoking it at the specified execution time
* @param task the Runnable to execute
* @param startTime the desired execution time for the task
* @return a ScheduledFuture representing pending completion of the task
*/
ScheduledFuture<?> schedule(Runnable task, Instant startTime);
/**
* Schedule the given Runnable, starting as soon as possible and invoking it with the given period
* @param task the Runnable to execute
* @param period the interval between successive executions
* @return a ScheduledFuture representing pending completion of the task
*/
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Duration period);
/**
* Schedule the given Runnable, invoking it at the specified execution time and subsequently with the given period
* @param task the Runnable to execute
* @param startTime the desired first execution time for the task
* @param period the interval between successive executions
* @return a ScheduledFuture representing pending completion of the task
*/
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Instant startTime, Duration period);
/**
* Schedule the given Runnable, starting as soon as possible and invoking it with the given delay between each execution
* @param task the Runnable to execute
* @param delay the delay between the completion of one execution and the start of the next
* @return a ScheduledFuture representing pending completion of the task
*/
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Duration delay);
/**
* Schedule the given Runnable, invoking it at the specified execution time and subsequently with the given delay between each execution
* @param task the Runnable to execute
* @param startTime the desired first execution time for the task
* @param delay the delay between the completion of one execution and the start of the next
* @return a ScheduledFuture representing pending completion of the task
*/
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Instant startTime, Duration delay);
}
/**
* Context object encapsulating last execution times and enabling the calculation of the next execution time
*/
public interface TriggerContext {
/**
* Return the last scheduled execution time of the task, or null if not scheduled before
* @return the last scheduled execution time
*/
Instant lastScheduledExecution();
/**
* Return the last actual execution time of the task, or null if not executed before
* @return the last actual execution time
*/
Instant lastActualExecution();
/**
* Return the last completion time of the task, or null if not completed before
* @return the last completion time
*/
Instant lastCompletion();
}
/**
* Common interface for trigger objects that may be used with a TaskScheduler
*/
@FunctionalInterface
public interface Trigger {
/**
* Determine the next execution time according to the given trigger context
* @param triggerContext context object encapsulating last execution times
* @return the next execution time as defined by the trigger, or null if the trigger won't fire anymore
*/
Instant nextExecution(TriggerContext triggerContext);
}Usage Examples:
// Basic task executor configuration
@Configuration
@EnableAsync
public class TaskExecutorConfig {
@Bean("taskExecutor")
public TaskExecutor taskExecutor() {
return new ThreadPoolTaskExecutorBuilder()
.corePoolSize(5)
.maxPoolSize(20)
.queueCapacity(100)
.threadNamePrefix("async-task-")
.waitForTasksToCompleteOnShutdown(true)
.awaitTerminationMillis(60000)
.build();
}
@Bean
public ThreadPoolTaskExecutorCustomizer taskExecutorCustomizer() {
return taskExecutor -> {
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.setTaskDecorator(runnable -> {
// Add security context or tracing context
return () -> {
try {
runnable.run();
} finally {
// Clean up context
}
};
});
};
}
}
// Task scheduling configuration
@Configuration
@EnableScheduling
public class SchedulingConfig {
@Bean("taskScheduler")
public TaskScheduler taskScheduler() {
return new ThreadPoolTaskSchedulerBuilder()
.poolSize(10)
.threadNamePrefix("scheduled-task-")
.waitForTasksToCompleteOnShutdown(true)
.awaitTerminationMillis(30000)
.build();
}
@Bean
public ThreadPoolTaskSchedulerCustomizer taskSchedulerCustomizer() {
return taskScheduler -> {
taskScheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
};
}
}
// Using async methods
@Service
public class EmailService {
@Async("taskExecutor")
public CompletableFuture<String> sendEmailAsync(String to, String subject, String body) {
// Simulate email sending
try {
Thread.sleep(2000);
String result = "Email sent to " + to;
return CompletableFuture.completedFuture(result);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return CompletableFuture.failedFuture(e);
}
}
@Async
public void sendNotificationAsync(String message) {
// Fire-and-forget notification
System.out.println("Sending notification: " + message);
}
}
// Using scheduled methods
@Component
public class ScheduledTasks {
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
System.out.println("Current time: " + Instant.now());
}
@Scheduled(cron = "0 0 1 * * ?") // Daily at 1 AM
public void performDailyTask() {
System.out.println("Performing daily maintenance task");
}
@Scheduled(fixedDelay = 10000, initialDelay = 5000)
public void performPeriodicTask() {
System.out.println("Performing periodic task with delay");
}
}
// Manual task scheduling
@Service
public class TaskService {
private final TaskScheduler taskScheduler;
private final TaskExecutor taskExecutor;
public TaskService(TaskScheduler taskScheduler, TaskExecutor taskExecutor) {
this.taskScheduler = taskScheduler;
this.taskExecutor = taskExecutor;
}
public void scheduleTask(Runnable task, Instant when) {
taskScheduler.schedule(task, when);
}
public void scheduleRepeatingTask(Runnable task, Duration period) {
taskScheduler.scheduleAtFixedRate(task, period);
}
public void executeAsync(Runnable task) {
taskExecutor.execute(task);
}
public void scheduleWithCustomTrigger(Runnable task) {
Trigger customTrigger = triggerContext -> {
// Custom logic to determine next execution time
Instant lastExecution = triggerContext.lastActualExecution();
if (lastExecution == null) {
return Instant.now().plusSeconds(10);
}
return lastExecution.plusMinutes(5);
};
taskScheduler.schedule(task, customTrigger);
}
}
// Virtual thread configuration (Java 21+)
@Configuration
public class VirtualThreadConfig {
@Bean
@ConditionalOnJava(range = ConditionalOnJava.Range.EQUAL_OR_NEWER, value = JavaVersion.TWENTY_ONE)
public SimpleAsyncTaskExecutor virtualThreadTaskExecutor() {
return new SimpleAsyncTaskExecutorBuilder()
.virtualThreadNamePrefix("virtual-task-")
.taskDecorator(runnable -> {
// Add virtual thread specific decorations
return runnable;
})
.build();
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-boot--spring-boot-starter