Search results
Spring Boot configuration to switch between ThreadPoolTaskExecutor and VirtualThreadTaskExecutor
Note:
Requires Java
21
, or Java 19, 20 preview releases.
TaskExecutorConfig.java
:
@Configuration
public class TaskExecutorConfig {
@Configuration
@ConditionalOnProperty(value = "spring.threads.virtual.enabled", havingValue = "true")
public static class VirtualThreadTaskExecutorConfig {
@Bean
public AsyncTaskExecutor taskExecutor() {
ThreadFactory factory = Thread.ofVirtual().name("virtual-thread-", 0).factory();
// Similar to Executors.newVirtualThreadPerTaskExecutor(factory), but with thread name.
return new TaskExecutorAdapter(Executors.newThreadPerTaskExecutor(factory));
}
}
@Configuration
@EnableAsync
@ConditionalOnProperty(value = "spring.threads.virtual.enabled", havingValue = "false", matchIfMissing = true)
// Uses spring.task.execution from config properties
public static class ThreadPoolTaskExecutorConfig {
}
}
application.yml
:
spring:
threads:
virtual:
enabled: <true or false>
task: # App's TaskExecutorConfig uses the 'ThreadPool' implementation if spring.threads.virtual.enabled is false or missing.
execution:
pool:
core-size: 20
max-size: 100
queue-capacity: 3000
thread-name-prefix: async-thread-
Usage
DefaultMessagingService.java
:
@Service
// ...
public class DefaultMessagingService implements MessagingService {
private final AsyncTaskExecutor taskExecutor;
// ...
@Override
public void sendActivationNotification(User user) {
this.taskExecutor.execute(() -> {
log.info("Sending activation email in a separate thread");
// ...
});
}
// ...
}