In a service I have 2 executorServices for different tasks:
It was easy to monitoring threads and adding resources and implement logic "skip this task if queue is full".
How this should be migrated to java 21? Is this logic "skip this task if queue is full" still can be implemented?
Example:
private ThreadPoolTaskExecutor getExecutor(AsyncProperties executorProperties, ContextDataDecorator contextDataDecorator) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setVirtualThreads(executorProperties.isVirtual());
executor.setTaskDecorator(contextDataDecorator);
executor.setCorePoolSize(executorProperties.getPoolSize());
executor.setMaxPoolSize(executorProperties.getPoolSize());
executor.setThreadNamePrefix(executorProperties.getThreadNamePrefix());
executor.setRejectedExecutionHandler((runnable, threadPoolExecutor) -> log.warn("Task {} was skipped by executor {}", runnable, threadPoolExecutor));
if (executorProperties.hasQueueCapacity()) {
executor.setQueueCapacity(executorProperties.getQueueCapacity());
}
executor.initialize();
return executor;
}
configs:
transactions.executor:
pool-size: 100
thread-name-prefix: transactions-async-executor-
queue-capacity: 200
virtual: true
family.executor:
pool-size: 50
queue-capacity: 100
thread-name-prefix: family-async-
The closest to Spring's ThreadPoolTaskExecutor (if TaskExecutor implementation is what really needed) is org.springframework.core.task.SimpleAsyncTaskExecutor:
SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor();
executor.setVirtualThreads(true);
executor.setTaskDecorator(contextDataDecorator);
executor.setThreadNamePrefix(executorProperties.getThreadNamePrefix());
return executor;
As virtual threads are used, core and max pool sizes are not applicable - there is no thread poll per se, each task is executed on a dedicated throw-away virtual thread which terminates upon task completion. Queue is not applicable as well, and the execution cannot be rejected.
It is assumed that the restrictions to ThreadPoolTaskExecutor pool sizes serve the purpose of preserving system resources, and are not the purpose of restricting simultaneous access to limited resources like JDBC Connections, what @Holger discussed in his comment. If this is a case then the above solution won't work, please then consult Cannot limit the concurrency of servlet requests using Spring Boot virtual threads with Tomcat SO thread, in particular a part which discusses a recommended way to use Semaphore in combination with Spring AOP.
Finally, keep in mind that virtual threads are daemons, so graceful shutdown of tasks, running by them, is not supported out of the box. SO thread Spring boot with java 21 virtual threads - is there a way to terminate gracefully? discusses that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With