转载请标明出处:

原文首发于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. C# url获取图片流转字符串

    //http url获取图片流转字符串 //string url = serverUrl.TrimEnd('/') + PUrl; //WebRequest request = WebRequest. ...

  2. 针对在webview模式中,小米魅族手机不支持html5原生video的control的解决办法![原创]

    其实,解决办法就是,重新写个control控制功能,.同样用流行的video.js可以实现 第一步就是增加个播放的图片..要不然没有按钮多难看! <div class="videoDi ...

  3. Redis简介及持久化

    Redis是一个key-value数据库,他不仅性能强劲,而且还具有复制特性以及为解决问题而生的独一无二的数据模型.可用于缓存.消息队列.发布.订阅消息.商品列表和评论列表等场景.Redis提供了5种 ...

  4. Java中的锁之乐观锁与悲观锁

    1.  分类一:乐观锁与悲观锁 a)悲观锁:认为其他线程会干扰本身线程操作,所以加锁 i.具体表现形式:synchronized关键字和lock实现类 b)乐观锁:认为没有其他线程会影响本身线程操作, ...

  5. IOS微信浏览器点击事件不起作用问题

    问题: $(document).on("click",".btn",function(){alert("1")}); 在微信浏览器上点击不起 ...

  6. es6新语法的使用

    1.声明变量: let 声明变量 作用域代码块作用域{} 尽在模块 先使用后声明 会报错 { let a= 12; alert(a) } let 不允许重复声明同一个变量 const 声明是一个常量, ...

  7. [原创]vs2012创建的ado.net模型无法实例化的问题

    最近从vs2010升级到vs2012,建立数据模型,发现生成的东西跟以前不一样了,而且也无法实例化使用.百度尝试了n种关键词,终于被我找到解决的方法.在这里记录一下. 1.打开设计器,也就是双击这个 ...

  8. Java IntelliJ IDEA 不能显示项目里的文件结构的解决方案

    按下列步骤操作:1. 关闭IDEA2.然后删除项目文件夹下的.idea文件夹3.重新用IDEA工具打开项目

  9. Windows 消息框架: SDK教程

    关键字:WindowsSDK 消息机制 http://www.codeproject.com/Articles/599/Windows-Message-Handling-Part-3 Handling ...

  10. C++异常安全的思考

    异常安全的代码是指,满足两个条件 1异常中立性 : 是指当你的代码(包括你调用的代码)引发异常时,这个异常 能保持原样传递到外层调用代码 2.异常安全性:  1,抛出异常后,资源不泄露, 2,抛出异常 ...