I am using Spring's Java Configuration with AsyncConfigurer:
@Configuration
@EnableAsync
public class AppConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(10);
executor.setThreadNamePrefix("MyExecutor-");
executor.initialize();
return executor;
}
}
Now suppose I have a method with @Async annotation and suppose its called 2 times already and 2 threads are still running. As per my understanding, any new call to it will be added in the queue with capacity 10. Now if I receive 11th Task, what will be the behaviour of it? will it reject the task as stated here: https://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html? or will the caller wait for a queue slot to get empty?
My Requirement is to not exeed a fix number of threads spawned using @Async method and to make the caller wait if max number of threads are reached. Will this be achieved if I use ConcurrentTaskExecutor with a fixed thread pool of a particular size?
I wanted to limit the number of possible threads along with not loosing any message. This requirement of mine was not fulfilled from the existing answers and I found another way to do it. Hence, posting it as an answer:
I made a Executor Bean as follows:
@Bean(name = "CustomAsyncExecutor")
public Executor customThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(5);
executor.setQueueCapacity(0);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("Async_Thread_");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}
And then using
@Async("CustomAsyncExecutor")
public void methodName(){
....
}
Given that when the threads are busy & when queue is full, new tasks get rejected,
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy())
helped me that when my 5 threads are busy, my invoker thread will execute the task & since my invoker thread is within the async function, it won't take any new tasks. Thus, I won't loose my tasks without increasing the queue size.