Hi I'm trying out Springs asynchronous executors and found you could use @Async. I would like to know if there is a possibility to use @Async within @Async, requirement being the need to delegate task to @Async method called within the first @Async method.
Eg : There are 100 files in a directory and need to create jobs processing 20 files in 5 threads.
If the two async methods are defined in two different classes, then you will be able to call the second async method from the first one. But, if they both are in the same class, the execution of the second method will happen inline in the thread processing the first method itself. Check out this answer for more details and some workarounds for the same.
For your specific case, you can define two thread pool executors, one for the first async method and another one for the second async method. The @Async annotation has a value parameter to which you can pass the thread pool executor that should be used.
Below is an example of using two executors.
@SpringBootApplication
@EnableAspectJAutoProxy
@EnableAsync
public class MultipleExecutorsExample {
@Bean
public ThreadPoolTaskExecutor executor1() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(10);
threadPoolTaskExecutor.setMaxPoolSize(10);
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
@Bean
public ThreadPoolTaskExecutor executor2() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(5);
threadPoolTaskExecutor.setMaxPoolSize(5);
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
public static void main(String[] args) throws BeansException, InterruptedException {
ConfigurableApplicationContext context = new SpringApplicationBuilder(MultipleExecutorsExample.class)
.web(WebApplicationType.NONE).build().run(args);
context.getBean(Service1.class).execute();
}
}
Service1 with the first async method
@Component
@Slf4j
public class Service1 {
@Autowired
private Service2 service2;
@Async("executor1")
public void execute() throws InterruptedException {
log.info("Sleeping for 5 seconds");
for (int i = 1; i <= 10; i++) {
service2.execute();
}
}
}
Service2 with the second async method
@Component
@Slf4j
public class Service2 {
@Async("executor2")
public void execute() throws InterruptedException {
log.info("Sleeping for 1 seconds");
Thread.sleep(1000);
}
}
The output from the program show that different executors are being used for the two async tasks.
018-05-30 18:44:27.557 INFO 19839 --- [ restartedMain] c.e.demo.tp.MultipleExecutorsExample : Started MultipleExecutorsExample in 1.926 seconds (JVM running for 2.407)
2018-05-30 18:44:27.567 INFO 19839 --- [ executor1-1] com.example.demo.tp.Service1 : Sleeping for 5 seconds
2018-05-30 18:44:27.570 INFO 19839 --- [ executor2-1] com.example.demo.tp.Service2 : Sleeping for 1 seconds
2018-05-30 18:44:27.570 INFO 19839 --- [ executor2-2] com.example.demo.tp.Service2 : Sleeping for 1 seconds
2018-05-30 18:44:27.570 INFO 19839 --- [ executor2-5] com.example.demo.tp.Service2 : Sleeping for 1 seconds
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