Springboot-async

来源:互联网 发布:淘宝木子禅佛珠怎么样 编辑:程序博客网 时间:2024/04/19 09:21

使用@Async实现异步调用

什么是”异步调用”与”同步调用”

“同步调用”就是程序按照一定的顺序依次执行,每一行程序代码必须等上一行代码执行完毕才能执行;”异步调用”则是只要上一行代码执行,无需等待结果的返回就开始执行本身任务。
通常情况下,”同步调用”执行程序所花费的时间比较多,执行效率比较差。所以,在代码本身不存在依赖关系的话,我们可以考虑通过”异步调用”的方式来并发执行。

“异步调用”

在 spring boot 框架中,只要提过@Async注解就能奖普通的同步任务改为异步调用任务。
注意: @Async所修饰的函数不要定义为static类型,这样异步调用不会生效

1. 开启@Async注解

在Spring Boot主类添加@EnableAsync注解,如下:

@SpringBootApplication@EnableAsync // 启用异步注解@ComponentScan(basePackages="com.ideabook")public class SpringbootStartApplication extends SpringBootServletInitializer {    public static void main(String[] args) {        SpringApplication.run(SpringbootStartApplication.class, args);    }}

2. 定义异步任务

定义Task类,创建三个处理函数分别模拟三个执行任务的操作,操作消耗时间随机取(10秒内)。

@Servicepublic class AsyncService {    public static Random random =new Random();    @Async    public Future<String> doTaskOne() throws Exception {        System.out.println("开始做任务一");        long start = System.currentTimeMillis();        Thread.sleep(random.nextInt(10000));        long end = System.currentTimeMillis();        System.out.println("完成任务一,耗时:" + (end - start) + "毫秒");        return new AsyncResult<>("任务一完成");    }    @Async    public Future<String> doTaskTwo() throws Exception {        System.out.println("开始做任务二");        long start = System.currentTimeMillis();        Thread.sleep(random.nextInt(10000));        long end = System.currentTimeMillis();        System.out.println("完成任务二,耗时:" + (end - start) + "毫秒");        return new AsyncResult<>("任务二完成");    }    @Async    public Future<String> doTaskThree() throws Exception {        System.out.println("开始做任务三");        long start = System.currentTimeMillis();        Thread.sleep(random.nextInt(10000));        long end = System.currentTimeMillis();        System.out.println("完成任务三,耗时:" + (end - start) + "毫秒");        return new AsyncResult<>("任务三完成");    }    @Async    public void  doTaskFour(){        System.out.println("开始做任务四");        long start = System.currentTimeMillis();        long count = 0;        for (int i = 0 ; i < 10000000; i ++){           count = count + i ;        }        long end = System.currentTimeMillis();        System.out.println("完成任务四,耗时:" + (end - start) + "毫秒");    }}

3. 创建Controller进行测试

注意@Autowired注入类,因为这个类已经被 Spring 管理了。如果使用 new 来获得线程类将不会执行异步效果,这里涉及到在 Spring 中使用多线程。

@Controller@RequestMapping("/async")public class AsyncController {    private AsyncService asyncService;    @Autowired    public AsyncController(AsyncService asyncService) {        this.asyncService = asyncService;    }    @RequestMapping("/test")    @ResponseBody    public String testAsync() throws Exception{        long start = System.currentTimeMillis();        Future<String> task1 = asyncService.doTaskOne();        Future<String> task2 = asyncService.doTaskTwo();        Future<String> task3 = asyncService.doTaskThree();        asyncService.doTaskFour();        while(true) { //等待功能全部完成后,再返回效果。类似于接口内部各个功能的异步执行,最后统一返回状态值。            if(task1.isDone() && task2.isDone() && task3.isDone()) {                // 三个任务都调用完成,退出循环                break;            }           // Thread.sleep(1000);        }        long end = System.currentTimeMillis();        System.out.println("任务全部完成,总耗时:" + (end - start) + "毫秒");        return "Success!!";    }}

备注:利用service中Future做为返回参数,可以对异步的操作进行管理。


文章转载自:[1]:http://blog.csdn.net/u011244202/article/details/54864528