1. Not working
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);
}
If it plays an asynchronous role, then theoretically it takes five seconds to end. But unfortunately, the output result is 10 seconds...
We know that spring AOP is implemented through a proxy, and @Async is similar, and requires proxy classes to enhance it. According to the above wording, it is a call of the class itself, which is equivalent to this. method. Can't serve as an agent.
2. How it works
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);
}
Asynchrony works.
The most important difference between the two is that the calling and asynchronous methods are not the same class. It is equivalent to calling the method with added asynchronous annotation through proxy.