解决@Async注解在springboot中不起作用

1. 不起作用的写法

Controller

   @Autowired
   private VehicleService vehicleService;
   
    @RequestMapping(value = "/queryBy", method = RequestMethod.GET)
    public CommonResponse queryList(@RequestParam(value = "vin", required = false) String vin)  {
        List vehicles = vehicleService.queryList(vin);
        return new CommonResponse(null);
    }

Service

public List queryList(String vin){
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
    //            Vector threads = new Vector();
        List> lists = new ArrayList<>(2);
        Future response = async("1");
        Future 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 send(String sources){
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return new AsyncResult<>(new CommonResponse(sources));
    }

    @Async
    public Future 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> 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 send(String sources){
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return new AsyncResult<>(new CommonResponse(sources));
    }

    @Async
    public Future async(String sources){
       return send(sources);
    }

异步起作用了。
在这里插入图片描述

两者最重要的区别是调用和异步方法所在类不是同一个。相当于调用增加了异步注解的方法时是通过代理来实现的。

你可能感兴趣的:(总结)