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