`

56. spring boot中使用@Async实现异步调用【从零开始学Spring Boot】

阅读更多

  

什么是异步调用

       “异步调用”对应的是“同步调用”,同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行;异步调用指程序在顺序执行时,不等待异步调用的语句返回结果就执行后面的程序。

 

同步调用

下面通过一个简单示例来直观的理解什么是同步调用:

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

package com.kfit.task;

 

import java.util.Random;

import org.springframework.stereotype.Component;

 

/**

 * 定义3个任务

 * @author Angel(QQ:412887952)

 * @version v.0.1

 */

@Component

publicclass Task1 {

    //定义一个随机对象.

    publicstatic Random random =new Random();

 

    //任务一;

    publicvoid doTaskOne() throws Exception {

        System.out.println("开始做任务一");

        longstart = System.currentTimeMillis();

        Thread.sleep(random.nextInt(10000));

        longend = System.currentTimeMillis();

        System.out.println("完成任务一,耗时:" + (end - start) + "毫秒");

    }

 

    //任务二;

    publicvoid doTaskTwo() throws Exception {

        System.out.println("开始做任务二");

        longstart = System.currentTimeMillis();

        Thread.sleep(random.nextInt(10000));

        longend = System.currentTimeMillis();

        System.out.println("完成任务二,耗时:" + (end - start) + "毫秒");

    }

 

    //任务3;

    publicvoid doTaskThree() throws Exception {

        System.out.println("开始做任务三");

        longstart = System.currentTimeMillis();

        Thread.sleep(random.nextInt(10000));

        longend = System.currentTimeMillis();

        System.out.println("完成任务三,耗时:" + (end - start) + "毫秒");

    }

 

}

 

编写一个访问方法:

//测试task1.

    @RequestMapping("/task1")

    public String task1() throws Exception{

       task1.doTaskOne();

       task1.doTaskTwo();

       task1.doTaskThree();

       return"task1";

    }

运行可以看到类似如下输出:

   开始做任务一

    完成任务一,耗时:4156毫秒

    开始做任务二

    完成任务二,耗时:557毫秒

    开始做任务三

    完成任务三,耗时:6171毫秒

 

异步调用

上述的同步调用虽然顺利的执行完了三个任务,但是可以看到执行时间比较长,若这三个任务本身之间不存在依赖关系,可以并发执行的话,同步调用在执行效率方面就比较差,可以考虑通过异步调用的方式来并发执行。

Spring Boot中,我们只需要通过使用@Async注解就能简单的将原来的同步函数变为异步函数,Task类改在为如下模式:

package com.kfit.task;

 

import java.util.Random;

 

import org.springframework.scheduling.annotation.Async;

import org.springframework.stereotype.Component;

 

/**

 * 定义3个任务

 * @author Angel(QQ:412887952)

 * @version v.0.1

 */

@Component

publicclass Task2 {

    //定义一个随机对象.

    publicstatic Random random =new Random();

 

    //任务一;

    @Async

    publicvoid doTaskOne() throws Exception {

        System.out.println("开始做任务一");

        longstart = System.currentTimeMillis();

        Thread.sleep(random.nextInt(10000));

        longend = System.currentTimeMillis();

        System.out.println("完成任务一,耗时:" + (end - start) + "毫秒");

    }

 

    //任务二;

    @Async

    publicvoid doTaskTwo() throws Exception {

        System.out.println("开始做任务二");

        longstart = System.currentTimeMillis();

        Thread.sleep(random.nextInt(10000));

        longend = System.currentTimeMillis();

        System.out.println("完成任务二,耗时:" + (end - start) + "毫秒");

    }

 

    //任务3;

    @Async

    publicvoid doTaskThree() throws Exception {

        System.out.println("开始做任务三");

        longstart = System.currentTimeMillis();

        Thread.sleep(random.nextInt(10000));

        longend = System.currentTimeMillis();

        System.out.println("完成任务三,耗时:" + (end - start) + "毫秒");

    }

 

}

       为了让@Async注解能够生效,还需要在Spring Boot的主程序中配置@EnableAsync,如下所示:

@SpringBootApplication

@EnableAsync

publicclass App {

    //省略其它代码

}

编写测试方法:

//测试task2.

    @RequestMapping("/task2")

    public String task2() throws Exception{

       task2.doTaskOne();

       task2.doTaskTwo();

       task2.doTaskThree();

       return"task2";

    }

 

此时可以反复执行单元测试,您可能会遇到各种不同的结果,比如:

开始做任务一

开始做任务二

开始做任务三

完成任务三,耗时:57毫秒

完成任务二,耗时:3621毫秒

 

完成任务一,耗时:7419毫秒

 

 

Spring Boot 系列博客】

à悟空学院:https://t.cn/Rg3fKJD

学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!

SpringBoot视频:http://t.cn/A6ZagYTi

Spring Cloud视频:http://t.cn/A6ZagxSR

SpringBoot Shiro视频:http://t.cn/A6Zag7IV

SpringBoot交流平台:https://t.cn/R3QDhU0

SpringData和JPA视频:http://t.cn/A6Zad1OH

SpringSecurity5.0视频:http://t.cn/A6ZadMBe

Sharding-JDBC分库分表实战http://t.cn/A6ZarrqS

分布式事务解决方案「手写代码」:http://t.cn/A6ZaBnIr

 

网易云课堂视频最新更新

第十一章 Spring Boot 日志

1、spring boot日志—理论

2、Spring Boot日志-logback

3、Spring Boot日志-log4j2

第十二章 Spring Boot 知识点2

1、spring boot 服务配置和部署

2、Spring Boot 定制URL匹配规则

 

 

历史章节

 

第一章 快速开始

1、Spring Boot之Hello World

2、Spring Boot之Hello World访问404

 

第二章 Spring Boot之JSON

1、spring boot返回json数据

2、Spring Boot完美使用FastJson解析JSON数据

 

第三章 Spring Boot热部署

1、Spring Boot热部署(springloader)

2、springboot + devtools(热部署)

 

第四章 Spring Boot数据库

1、Spring Boot JPA/Hibernate/Spring Data概念

2、Spring Boot JPA-Hibernate

3、Spring Boot Spring Data JPA介绍

4、Spring Boot JdbcTemplate

5、Spring Boot集成MyBatis

 

第五章 web开发

1、全局异常捕捉

2、配置server信息

3、spring boot使用thymeleaf

4、Spring Boot 使用freemarker

5、Spring Boot添加JSP支持

 

第六章 定时任务

1、Spring Boot定时任务

2、Spring Boot 定时任务升级篇(动态修改cron参数)

3、Spring Boot 定时任务升级篇(动态添加修改删除定时任务)

4、Spring Boot 定时任务升级篇(集群/分布式下的定时任务说明)

5、Spring Boot Quartz介绍

6、Spring Boot Quartz在Java Project中使用

7、Spring Boot 集成Quartz普通使用

8、Spring Boot 集成Quartz升级版

9、Spring Boot 集成Quartz二次升级版

10、Spring Boot 集成Quartz-Job如何自动注入Spring容器托管的对象

 

第七章 Spring Boot MyBatis升级篇

1、Spring Boot MyBatis升级篇-注解

2、Spring Boot MyBatis升级篇-注解-自增ID

3、Spring Boot MyBatis升级篇-注解-增删改查

4、Spring Boot MyBatis升级篇-注解-分页查询

5、Spring Boot MyBatis升级篇-注解-分页PageHelper不生效

6、Spring Boot MyBatis升级篇-注解- mybatic insert异常:BindingException: Parameter 'name' not found

7、Spring Boot MyBatis升级篇-注解- #和$符号特别篇

8、Spring Boot MyBatis升级篇-注解-@Result

9、Spring Boot MyBatis升级篇-注解-动态SQL(if test)-方案一:<script>

10、Spring Boot MyBatis升级篇-注解-动态SQL(if test)-方案二:@Provider

11、Spring Boot MyBatis升级篇-注解-动态SQL-参数问题

12、Spring Boot MyBatis升级篇-注解-特别篇:@MapperScan和@Mapper

13、Spring Boot MyBatis升级篇-XML

14、Spring Boot MyBatis升级篇-XML-自增ID

15、Spring Boot MyBatis升级篇-XML-增删改查

16、Spring Boot MyBatis升级篇-XML-分页查询

17、Spring Boot MyBatis升级篇-XML-分页PageHelper不生效

18、Spring Boot MyBatis升级篇-XML-动态SQL(if test)

19、Spring Boot MyBatis升级篇-XML-注解-初尝试

20、Spring Boot MyBatis升级篇- pagehelper替换为pagehelper-spring-boot-starter

 

第八章 Spring Boot 知识点1

1、Spring Boot 拦截器HandlerInterceptor

2、Spring Boot启动加载数据CommandLineRunner

3、Spring Boot环境变量读取和属性对象的绑定

4、Spring Boot使用自定义的properties

5、Spring Boot使用自定义的properties

6、Spring Boot使用@SpringBootApplication

7、Spring Boot 监控和管理生产环境

 

第十章 Spring Boot 打包部署

1、Spring Boot打包部署((提供Linux的sh文件))

 

第十一章 Spring Boot 日志

1、spring boot日志—理论

2、Spring Boot日志-logback

 

3、Spring Boot日志-log4j2

 

更多查看博客: http://412887952-qq-com.iteye.com/

 

分享到:
评论
10 楼 林祥纤 2017-08-29  
恋无涯 写道
楼主应该分个类别,我这智商跟不上你排版  
开玩笑!
真的  分个类别比你在每篇里填上链接清晰多了


恩。
9 楼 恋无涯 2017-08-29  
楼主应该分个类别,我这智商跟不上你排版  
开玩笑!
真的  分个类别比你在每篇里填上链接清晰多了
8 楼 林祥纤 2016-11-27  
k88520 写道
博主 我是你的脑残粉


O(∩_∩)O~~
7 楼 k88520 2016-11-23  
博主 我是你的脑残粉
6 楼 林祥纤 2016-10-05  
qq1488888 写道
博主你好,其实一直很想知道异步要返回结果要前端的话怎么做???


前端异步应该是servlet的异步处理,你可以了解下。
5 楼 qq1488888 2016-10-05  
博主你好,其实一直很想知道异步要返回结果要前端的话怎么做???
4 楼 林祥纤 2016-07-06  
sunbin 写道
每篇都看了,简单明了,没有问题。 十分感谢。
希望后期可以结合spring cloud的知识就更好了。


这个只能看时间安排了...
3 楼 sunbin 2016-07-06  
每篇都看了,简单明了,没有问题。 十分感谢。
希望后期可以结合spring cloud的知识就更好了。
2 楼 林祥纤 2016-07-05  
sunbin 写道
用了很多次,现在才搞明白。


您是在哪里卡主了,有什么地方我可以帮您的吗,或者您觉得文章可以在哪些方面可以在提升下。
1 楼 sunbin 2016-07-05  
用了很多次,现在才搞明白。

相关推荐

Global site tag (gtag.js) - Google Analytics