1. 不起作用的写法
Controller
@Autowired
private VehicleService vehicleService;
@RequestMapping(value = "/queryBy", method = RequestMethod.GET)
public CommonResponse queryList(@RequestParam(value = "vin", required = false) String vin) {
List<Vehicle> vehicles = vehicleService.queryList(vin);
return new CommonResponse(null);
}
Service
public List<Vehicle> queryList(String vin){
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// Vector<Thread> threads = new Vector<Thread>();
List<Future<CommonResponse>> lists = new ArrayList<>(2);
Future<CommonResponse> response = async("1");
Future<CommonResponse> response2 = async("2");
lists.add(response);
lists.add(response2);
while(true){
boolean b = lists.stream().anyMatch(Future::isDone);
if(b){
System.out.println(lists.toString());
stopWatch.stop();
break;
}
}
System.out.println("cost time is : " + (stopWatch.getTotalTimeMillis()) / 1000);
return null;
}
public Future<CommonResponse> send(String sources){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new AsyncResult<>(new CommonResponse(sources));
}
@Async
public Future<CommonResponse> async(String sources){
return send(sources);
}
如果起到异步的作用,那么理论上是耗时五秒就结束。但是很不幸,输出结果是10秒…
我们知道spring AOP是通过代理来实现的,@Async也类似,需要代理类来增强,按上面的写法是类本身的调用,相当于this.方法,这样是起不到代理的作用的。
2. 起作用的写法
Controller
@Autowired
private VehicleService vehicleService;
@RequestMapping(value = "/queryBy", method = RequestMethod.GET)
public CommonResponse queryList(@RequestParam(value = "vin", required = false) String vin) throws Exception {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
List<Future<CommonResponse>> result = Lists.newArrayList();
Arrays.asList("1", "2").stream().forEach(p-> result.add(vehicleService.async(p)));
while (true){
boolean b = result.stream().allMatch(Future::isDone);
if(b){
stopWatch.stop();
break;
}
}
System.out.println("cost time :" + (stopWatch.getTotalTimeMillis()) / 1000);
return new CommonResponse(null);
}
Service
public Future<CommonResponse> send(String sources){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new AsyncResult<>(new CommonResponse(sources));
}
@Async
public Future<CommonResponse> async(String sources){
return send(sources);
}
异步起作用了。
两者最重要的区别是调用和异步方法所在类不是同一个。相当于调用增加了异步注解的方法时是通过代理来实现的。