spring boot项目
服务类上注解@EnableAsync开启扫描方法上的@Async注解,当其他bean调用这个被@Async注解的方法时,spring会通过代理,在子线程里执行,达到异步调用与并行执行的目的
【注意】
- 不能在类内部 (bean内部,spring无法感知) 调用@Async (就是要),spring无法感知到,所以不会再子线程执行
@Async生效需要一个bean(controller)调用另一个bean(service)的方法 - 如果有返回值,返回值是Future类型的包装
//controller.java
@Autowired
private FakeService fakeService;
@GetMapping("/slow")
public String slow() {
StopWatch watch = new StopWatch("my watch");
//通常模式service调用
watch.start("slowServiceNormal");
fakeService.slowService();
fakeService.slowService();
watch.stop();
//异步模式,在子线程各自独立调用service,有返回值
watch.start("slowService async with return");
Future<Long> res1 = fakeService.slowServiceAsync();
Future<Long> res2 = fakeService.slowServiceAsync();
try {
res1.get();
res2.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
watch.stop();
//无返回值调用,直接返回,子线程继续工作
watch.start("slowServiceNoReturn");
fakeService.slowServiceNoReturn();
fakeService.slowServiceNoReturn();
watch.stop();
System.out.println(watch.prettyPrint());
return "done";
}
package boottest;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
/**
* @author zhanghui
* @date 2019/5/9
*/
@Service
@EnableAsync
public class FakeService {
public long slowService(){
System.out.println("slowServiceNormal");
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(5));
System.out.println("slowServiceNormal done");
return 5;
}
//异步调用,有返回值,必须是Future类型,不然报错
@Async
public Future<Long> slowServiceAsync(){
System.out.println("slowServiceAsync");
return new AsyncResult(slowService());
}
@Async
public void slowServiceNoReturn(){
System.out.println("slowServiceNoReturn");
slowService();
}
}