SpringBoot非官方教程 | 第二十三篇: 异步方法
转载请标明出处:
原文首发于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 教程:springBoot非官方教程 | 文章汇总
- 更多springcoud 教程:史上最简单的 SpringCloud 教程 | 文章汇总
扫码关注公众号有惊喜
(转载本站文章请注明作者和出处 方志朋的博客)
SpringBoot非官方教程 | 第二十三篇: 异步方法的更多相关文章
- SpringBoot非官方教程 | 第二十篇: 处理表单提交
转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot-form/ 本文出自方志朋的博客 这篇文件主要介 ...
- SpringBoot非官方教程 | 第十三篇:springboot集成spring cache
转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot13-springcache/ 本文出自方志朋的博 ...
- SpringBoot非官方教程 | 第二十一篇: springboot集成JMS
转载请标明出处: http://blog.csdn.net/forezp/article/details/71024024 本文出自方志朋的博客 springboot对JMS提供了很好的支持,对其做了 ...
- (转) SpringBoot非官方教程 | 第二十四篇: springboot整合docker
这篇文篇介绍,怎么为 springboot程序构建一个Docker镜像.docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源.Docker 可以让开发者打包他们的 ...
- SpringBoot非官方教程 | 第二十六篇: sprinboot整合elk,搭建实时日志平台
转载请标明出处: 原文首发于https://www.fangzhipeng.com/springboot/2017/07/11/sprinboot25-elk/ 本文出自方志朋的博客 这篇文章主要介绍 ...
- SpringBoot非官方教程 | 第二十四篇: springboot整合docker
转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot24-docker/ 本文出自方志朋的博客 这篇文 ...
- SpringBoot非官方教程 | 第二十二篇: 创建含有多module的springboot工程
转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springbot22-modules/ 本文出自方志朋的博客 这篇文 ...
- (转) SpringBoot非官方教程 | 第二篇:Spring Boot配置文件详解
springboot采纳了建立生产就绪spring应用程序的观点. Spring Boot优先于配置的惯例,旨在让您尽快启动和运行.在一般情况下,我们不需要做太多的配置就能够让spring boot正 ...
- (转)SpringBoot非官方教程 | 第七篇:springboot开启声明式事务
springboot开启事务很简单,只需要一个注解@Transactional 就可以了.因为在springboot中已经默认对jpa.jdbc.mybatis开启了事事务,引入它们依赖的时候,事物就 ...
随机推荐
- C# url获取图片流转字符串
//http url获取图片流转字符串 //string url = serverUrl.TrimEnd('/') + PUrl; //WebRequest request = WebRequest. ...
- 针对在webview模式中,小米魅族手机不支持html5原生video的control的解决办法![原创]
其实,解决办法就是,重新写个control控制功能,.同样用流行的video.js可以实现 第一步就是增加个播放的图片..要不然没有按钮多难看! <div class="videoDi ...
- Redis简介及持久化
Redis是一个key-value数据库,他不仅性能强劲,而且还具有复制特性以及为解决问题而生的独一无二的数据模型.可用于缓存.消息队列.发布.订阅消息.商品列表和评论列表等场景.Redis提供了5种 ...
- Java中的锁之乐观锁与悲观锁
1. 分类一:乐观锁与悲观锁 a)悲观锁:认为其他线程会干扰本身线程操作,所以加锁 i.具体表现形式:synchronized关键字和lock实现类 b)乐观锁:认为没有其他线程会影响本身线程操作, ...
- IOS微信浏览器点击事件不起作用问题
问题: $(document).on("click",".btn",function(){alert("1")}); 在微信浏览器上点击不起 ...
- es6新语法的使用
1.声明变量: let 声明变量 作用域代码块作用域{} 尽在模块 先使用后声明 会报错 { let a= 12; alert(a) } let 不允许重复声明同一个变量 const 声明是一个常量, ...
- [原创]vs2012创建的ado.net模型无法实例化的问题
最近从vs2010升级到vs2012,建立数据模型,发现生成的东西跟以前不一样了,而且也无法实例化使用.百度尝试了n种关键词,终于被我找到解决的方法.在这里记录一下. 1.打开设计器,也就是双击这个 ...
- Java IntelliJ IDEA 不能显示项目里的文件结构的解决方案
按下列步骤操作:1. 关闭IDEA2.然后删除项目文件夹下的.idea文件夹3.重新用IDEA工具打开项目
- Windows 消息框架: SDK教程
关键字:WindowsSDK 消息机制 http://www.codeproject.com/Articles/599/Windows-Message-Handling-Part-3 Handling ...
- C++异常安全的思考
异常安全的代码是指,满足两个条件 1异常中立性 : 是指当你的代码(包括你调用的代码)引发异常时,这个异常 能保持原样传递到外层调用代码 2.异常安全性: 1,抛出异常后,资源不泄露, 2,抛出异常 ...