转载请标明出处:

原文首发于https://www.fangzhipeng.com/springboot/2017/07/11/springboot-ansy/

本文出自方志朋的博客

这篇文章主要介绍在springboot 使用异步方法,去请求github api.

创建工程

在pom文件引入相关依赖:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>

创建一个接收数据的实体:

@JsonIgnoreProperties(ignoreUnknown=true)
public class User { private String name;
private String blog; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getBlog() {
return blog;
} public void setBlog(String blog) {
this.blog = blog;
} @Override
public String toString() {
return "User [name=" + name + ", blog=" + blog + "]";
} }

创建一个请求的 githib的service:

@Service
public class GitHubLookupService { private static final Logger logger = LoggerFactory.getLogger(GitHubLookupService.class); private final RestTemplate restTemplate; public GitHubLookupService(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.build();
} @Async
public Future<User> findUser(String user) throws InterruptedException {
logger.info("Looking up " + user);
String url = String.format("https://api.github.com/users/%s", user);
User results = restTemplate.getForObject(url, User.class);
// Artificial delay of 1s for demonstration purposes
Thread.sleep(1000L);
return new AsyncResult<>(results);
} }

通过,RestTemplate去请求,另外加上类@Async 表明是一个异步任务。

开启异步任务:


@SpringBootApplication
@EnableAsync
public class Application extends AsyncConfigurerSupport { public static void main(String[] args) {
SpringApplication.run(Application.class, args);
} @Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("GithubLookup-");
executor.initialize();
return executor;
} }

通过@EnableAsync开启异步任务;并且配置AsyncConfigurerSupport,比如最大的线程池为2.

测试

测试代码如下:

@Component
public class AppRunner implements CommandLineRunner { private static final Logger logger = LoggerFactory.getLogger(AppRunner.class); private final GitHubLookupService gitHubLookupService; public AppRunner(GitHubLookupService gitHubLookupService) {
this.gitHubLookupService = gitHubLookupService;
} @Override
public void run(String... args) throws Exception {
// Start the clock
long start = System.currentTimeMillis(); // Kick of multiple, asynchronous lookups
Future<User> page1 = gitHubLookupService.findUser("PivotalSoftware");
Future<User> page2 = gitHubLookupService.findUser("CloudFoundry");
Future<User> page3 = gitHubLookupService.findUser("Spring-Projects"); // Wait until they are all done
while (!(page1.isDone() && page2.isDone() && page3.isDone())) {
Thread.sleep(10); //10-millisecond pause between each check
} // Print results, including elapsed time
logger.info("Elapsed time: " + (System.currentTimeMillis() - start));
logger.info("--> " + page1.get());
logger.info("--> " + page2.get());
logger.info("--> " + page3.get());
} }

启动程序,控制台会打印:

2017-04-30 13:11:10.351 INFO 1511 — [ GithubLookup-1] com.forezp.service.GitHubLookupService : Looking up PivotalSoftware

2017-04-30 13:11:10.351 INFO 1511 — [ GithubLookup-2] com.forezp.service.GitHubLookupService : Looking up CloudFoundry

2017-04-30 13:11:13.144 INFO 1511 — [ GithubLookup-2] com.forezp.service.GitHubLookupService : Looking up Spring-Projects

耗时:3908

分析:可以卡的前面2个方法分别在GithubLookup-1 和GithubLookup-2执行,第三个在GithubLookup-2执行,注意因为在配置线程池的时候最大线程为2.如果你把线程池的个数为3的时候,耗时减少。

如果去掉@Async,你会发现,执行这三个方法都在main线程中执行。耗时总结,如下:

2017-04-30 13:13:00.934 INFO 1527 — [ main] com.forezp.service.GitHubLookupService : Looking up PivotalSoftware

2017-04-30 13:13:03.571 INFO 1527 — [ main] com.forezp.service.GitHubLookupService : Looking up CloudFoundry

2017-04-30 13:13:04.865 INFO 1527 — [ main] com.forezp.service.GitHubLookupService : Looking up Spring-Projects

耗时:5261

通过这一个小的栗子,你应该对异步任务有了一定的了解。

参考资料

https://spring.io/guides/gs/async-method/

源码下载

https://github.com/forezp/SpringBootLearning

优秀文章推荐:




扫码关注公众号有惊喜

(转载本站文章请注明作者和出处 方志朋的博客

SpringBoot非官方教程 | 第二十三篇: 异步方法的更多相关文章

  1. SpringBoot非官方教程 | 第二十篇: 处理表单提交

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot-form/ 本文出自方志朋的博客 这篇文件主要介 ...

  2. SpringBoot非官方教程 | 第十三篇:springboot集成spring cache

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot13-springcache/ 本文出自方志朋的博 ...

  3. SpringBoot非官方教程 | 第二十一篇: springboot集成JMS

    转载请标明出处: http://blog.csdn.net/forezp/article/details/71024024 本文出自方志朋的博客 springboot对JMS提供了很好的支持,对其做了 ...

  4. (转) SpringBoot非官方教程 | 第二十四篇: springboot整合docker

    这篇文篇介绍,怎么为 springboot程序构建一个Docker镜像.docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源.Docker 可以让开发者打包他们的 ...

  5. SpringBoot非官方教程 | 第二十六篇: sprinboot整合elk,搭建实时日志平台

    转载请标明出处: 原文首发于https://www.fangzhipeng.com/springboot/2017/07/11/sprinboot25-elk/ 本文出自方志朋的博客 这篇文章主要介绍 ...

  6. SpringBoot非官方教程 | 第二十四篇: springboot整合docker

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot24-docker/ 本文出自方志朋的博客 这篇文 ...

  7. SpringBoot非官方教程 | 第二十二篇: 创建含有多module的springboot工程

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springbot22-modules/ 本文出自方志朋的博客 这篇文 ...

  8. (转) SpringBoot非官方教程 | 第二篇:Spring Boot配置文件详解

    springboot采纳了建立生产就绪spring应用程序的观点. Spring Boot优先于配置的惯例,旨在让您尽快启动和运行.在一般情况下,我们不需要做太多的配置就能够让spring boot正 ...

  9. (转)SpringBoot非官方教程 | 第七篇:springboot开启声明式事务

    springboot开启事务很简单,只需要一个注解@Transactional 就可以了.因为在springboot中已经默认对jpa.jdbc.mybatis开启了事事务,引入它们依赖的时候,事物就 ...

随机推荐

  1. 1.Vue.js的常用指令

      Vue.js介绍 Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得 ...

  2. 深入理解JavaScript系列(19):求值策略(Evaluation strategy)

    介绍 本章,我们将讲解在ECMAScript向函数function传递参数的策略. 计算机科学里对这种策略一般称为“evaluation strategy”(大叔注:有的人说翻译成求值策略,有的人翻译 ...

  3. [转]Oracle ROWNUM用法和分页查询总结

    本文转自:http://blog.csdn.net/fw0124/article/details/42737671 ****************************************** ...

  4. Java Socket通信示例

    Socket分为ServerSocket和Socket两大类: 其中ServerSocket用于服务器端,可以通过accept方法监听请求,监听到请求后返回Socket: Socket用户具体完成数据 ...

  5. 修改K3数据是简介方法

    如  及时库存里有个别产品库存没有库位  是*号的 这个时候  我们创建一个其他出库单,把这个没有库位的产品输入进去,库位随便写个 如002 保存,审核不了的  会提示负库存 去后台找到此单据号 修改 ...

  6. 注解实现AOP

    package com.dch.service.aop; import java.text.SimpleDateFormat; import java.util.Arrays; import java ...

  7. js CheckBox 全选、反选

    <h3>你最喜欢的水果是?</h3> <label><input type="checkbox"/>苹果</label> ...

  8. js如何完整的显示较长的数字

    试试下面一行吧 Math.pow(10, 99).toLocaleString().split(',').join('') toLocaleString([character]) 方法会将其对象转换成 ...

  9. LESS初体验

    将一个变量赋值给另一个变量,用引号:@white: 'color-white';,使用另一个变量,需要双@@符号:p {color: @@white;}. 而以这样进行变量的赋值:@white: @c ...

  10. pl/sql 存储过程执行execute immediate 卡住

    在存储过程中,执行了create table.update table.insert into table 但是在使用pl/sql的存储过程调试的时候,一有问题就直接卡住(标识:执行中.....) 后 ...