Spring async method called from another async method

只谈情不闲聊 提交于 2019-12-28 11:53:13

问题


I'm using Spring 4 and I've noticed an odd behaviour... if I'm calling an async method multiple times from a normal instance method then they are all called in different threads and finish at random times. But if I call multiple times an async method from another async method then they finish 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'm using the default async executor. Should I use a different one? However this executor do not reuse any threads and starts another one every time so it should be fine... Can it be just a coincidence? But I've tried like more than 10 times and if I revert back to non-async for the first method then they finish randomly


回答1:


What you are describing is a classic pitfall of Spring AOP.

In short, for Spring to be able to provide the async behavior it needs to create a proxy for your class at runtime. The proxy then does whatever it needs to do before and/or after calling your code. But in your case, the proxy mechanism is not being applied for the second method.

When a bean of your class is injected via Spring into some other component, Spring really injects the proxy instead. Therefor the relevant method of the proxy is called. However, when you are calling a method from inside the class, the limitations of Spring AOP mean the proxy never comes into play, but instead the regular method is called - with no extra features.

That is why asyncMethod is always executing on the same thread as the other method in the same class that called it.

Check out this excellent blog post as well as this part of Spring documentation.

There are some ways around the problem (check out this) that don't require you to refactor your code, but if you want async to work on both methods no matter what, the simplest thing to do is refactor the second method into another class.



来源:https://stackoverflow.com/questions/24898547/spring-async-method-called-from-another-async-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!