我编写了一段代码来检查Spring框架中的@Async
注释行为。
@RequestMapping( value="/async" , method = RequestMethod.GET)
public ModelAndView AsyncCall(HttpServletRequest request)
{
async1();
async2();
return new ModelAndView("firstpage");
}
@Async
private void async1(){
System.out.println("Thread 1 enter");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread 1 exit");
}
@Async
private void async2(){
System.out.println("Thread 2 enter");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread 2 exit");
}
此代码的输出如下。
Thread 1 enter
Thread 1 exit
Thread 2 enter
Thread 2 exit
通过查看此输出,似乎这两个@Async
函数调用本身是同步的。
据我所知,这两个是不同的线程,应该自己异步运行。
根据弹出的代理调用日志更改代码后打印就像。
主线程名称:http-apr-8080-exec-8
Thread 1 enter
Async-1 Thread Name: neutrinoThreadPoolExecutor-1
Thread 1 exit
Thread 2 enter
Async-2 Thread Name: neutrinoThreadPoolExecutor-1
Thread 2 exit
两个异步调用的线程名称相同,但似乎不呈现异步行为。
答案 0 :(得分:5)
@Async
对我不起作用的情况
@EnableAsync
失踪@Async
方法不公开@Async
带注释的方法是从同一个类的另一个方法调用的。可能绕过异步代理代码并只调用普通方法。答案 1 :(得分:1)
您是否在Spring Application中启用了Async?在Spring Boot中,您可以执行类似的操作。
@SpringBootApplication
@EnableAsync
public class Application extends AsyncConfigurerSupport {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("GithubLookup-");
executor.initialize();
return executor;
}
}
@EnableAsync注释切换Spring在后台线程池中运行@Async方法的能力。
答案 2 :(得分:1)
您必须从当前班级以外的地方调用这些方法。否则 spring magic 将无法执行。
所以尝试这样的事情:
@Inject
MyAsyncService asyncService;
@RequestMapping( value="/async" , method = RequestMethod.GET)
public ModelAndView AsyncCall(HttpServletRequest request) {
asyncService.async1();
return new ModelAndView("firstpage");
}
<强> MyAsyncService 强>
@Component
public MyAsyncService {
@Async
public void async1() {
//code
}
}
答案 3 :(得分:1)
Spring @Async
注释有两条规则需要遵循。
public
种方法原因很简单 - 该方法需要公开才能被代理。 并且自我调用不起作用,因为它绕过代理并直接调用底层方法。