Solve the @Async annotation does not work in springboot

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...
Insert picture description here
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.
Insert picture description here

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.

Guess you like

Origin blog.csdn.net/huangdi1309/article/details/89712646