Java – spring asynchronous method called from another asynchronous method
I'm using spring 4 and I noticed a strange behavior... If I call asynchronous methods multiple times from a regular instance method, they are called in different threads and completed at random time But if I call an asynchronous method multiple times from another asynchronous method, they are completed in order I have something like this:
@Async public void nonAsyncMethod() { for (int i = 0; i < 30; i++) { asyncMethod(); } } @Async public void asyncMethod() { ... something here }
I am using the default asynchronous actuator Should I use a different one? However, this performer does not reuse any thread, starting another thread at a time, so it should be good... Is it just a coincidence? But I've tried more than a dozen times. If I return to the non synchronization of the first method, they are completed at random
Solution
What you describe is the classic trap of spring AOP
In short, for spring, you can provide asynchronous behavior, which requires creating a proxy for your class at run time The agent then performs whatever needs to be done before and / or after calling your code But in your case, the proxy mechanism is not applied to the second method
When the bean of your class is injected into other components through spring, spring will really inject proxy Therefore, the relevant methods of the agent are called However, when you invoke a method from a class, the limitation of Spring AOP means that the agent will not function, instead of calling the conventional method without additional functions.
This is why asyncmethod always executes on the same thread as another method in the same class that calls it
Check this excellent blog posts and spring documents in this section
There are some ways to solve the problem of not refactoring code (see this), but if you want to work asynchronously on two methods, no matter what, the easiest way is to refactor the second method into another class