SpringBoot专栏:配置异步调用结合线程池玩出新花样,做不一样的教程
前言
异步(async)方法:用于异步执行其他工作,然后立即返回到调用方法
本章节将讲解springboot 如何配置异步方法,朋友有留言说期待看到springCloud等高阶技能点方面的文章,好的,不用着急,马上即将开启下一专栏,毕竟微服务才是自己所擅长的,SpringBoot专栏即将结束,但是在即将结束的几章里面,也不会让朋友失望,简单的springboot异步调用配置也尝试加一些其他的知识点。
虽然简单,但是我们要学着玩出不一样的demo(通过demo学习更多的技能点)
希望demo不再是demo而是让我们学习技能点最快速的方式。
Demo开始
pom引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
创建一个service(注意sayHallo 加上 @Async)
@Service
public class SleepService {
/**
*异步问候
* @param name
* @return
*/
@Async
public Future<String> sayHallo(String name){
try {
//休眠10秒
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new AsyncResult<String>("异步您好"+name);
}
/**
*问候【非异步】
* @param name
* @return
*/
public String sayHallo1(String name){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "非异步,您好-》"+name;
}
}
创建controller
启动类(注意加上@EnableAsync )
@SpringBootApplication
@EnableAsync
public class Springboot10EmailAsyncApplication extends AsyncConfigurerSupport {
public static void main(String[] args) {
SpringApplication.run(Springboot10EmailAsyncApplication.class, args);
}
//初始化线程池
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("springboot-async-");
executor.initialize();
return executor;
}
}
测试分析
但访问controller: ip/hello/springboot
当访问:异步方法sayHallo()的服务,此时因为是异步的所以controller可以快速的返回处理结果
当访问:非异步方法sayHallo1()的服务,因为是非异步的,业务方法中还有10秒的休眠,所以controller需要等待业务方法处理完后方可返回处理结果。
End?
汇总:异步方法实现很简单共2步:
1)启动类@EnableAsync开启异步任务
2)业务方法上@Async 表明是一个异步任务
是不是本章节就结束呢?No
细心的同学会发现了sayHallo()方法返回的是Future类型,那我们是不也应该来了解下。
启动类初始化了线程池,那是不是也应该了解下?
之前SpringBoot 事件监听回调知识点,是不是这个demo也可"小试牛刀"一下?
所以有了下面的一个测试方法
温故知新
新业务:当项目启动之后(监听回调),采用线程池异步调用sayHall()方法(线程池和Future用法),并分析测试结果(收获新旧技能点)
新的监听测试类
@Component
public class TestListener implements CommandLineRunner {
private static final Logger logger = LoggerFactory.getLogger(CommandLineRunner.class);
@Autowired
private final SleepService sleepService;
public TestListener(SleepService sleepService) {
this.sleepService = sleepService;
}
@Override
public void run(String... args) throws Exception {
long start = System.currentTimeMillis();
Future<String> name1 = sleepService.sayHallo("springBoot-1");
Future<String> name2 = sleepService.sayHallo("springBoot-2");
Future<String> name3 = sleepService.sayHallo("springBoot-3");
Future<String> name4 = sleepService.sayHallo("springBoot-4");
logger.info("异步运行用时: " + (System.currentTimeMillis() - start));
logger.info("线程池初始化调用,得到返回结果");
logger.info("开始测试1{}",name1.get());
logger.info("开始测试2{}",name2.get());
logger.info("开始测试3{}",name3.get());
logger.info("开始测试4{}",name4.get());
}
}
输出日志结果:
2018-12-30 16:18:36.378 INFO 8580 --- [ restartedMain] o.s.boot.CommandLineRunner : 异步运行用时: 9
2018-12-30 16:18:36.378 INFO 8580 --- [ restartedMain] o.s.boot.CommandLineRunner : 线程池初始化调用,得到返回结果
2018-12-30 16:18:46.389 INFO 8580 --- [ restartedMain] o.s.boot.CommandLineRunner : 开始测试1异步您好springBoot-1
2018-12-30 16:18:46.389 INFO 8580 --- [ restartedMain] o.s.boot.CommandLineRunner : 开始测试2异步您好springBoot-2
2018-12-30 16:18:56.390 INFO 8580 --- [ restartedMain] o.s.boot.CommandLineRunner : 开始测试3异步您好springBoot-3
2018-12-30 16:18:56.390 INFO 8580 --- [ restartedMain] o.s.boot.CommandLineRunner : 开始测试4异步您好springBoot-4
分析:
1.测试类 implements CommandLineRunner:表明这是一个事件监听回调,等项目启动成功运行测试方法run()
2.“异步运行用时: 9” 日志表明:上面4个调用方法,是异步的,所以用时9毫秒(异步调用)
3.“开始测试1..” 和 "开始测试2.." 打印日志时间是16:18:46 而其它是稍微久一点:因为在配置线程池的时候最大线程为2
线程池部分参数
4.什么是Future模式
Future模式是多线程开发中非常常见的一种设计模式。它的核心思想是异步调用。当我们需要调用一个函数方法时。如果这个函数执行很慢,那么我们就要进行等待。但有时候,我们可能并不急着要结果。因此,我们可以让被调用者立即返回,让他在后台慢慢处理这个请求。对于调用者来说,则可以先处理一些其他任务,在真正需要数据的场合再去尝试获取需要的数据。
使用Future模式,获取数据的时候无法立即得到需要的数据。而是先拿到一个契约,你可以再将来需要的时候再用这个契约去获取需要的数据,
至于Future其他的方法我们可以继续了解,在此不展开深入讨论(后面并发、多线程编程会详细介绍)
End?Yes
本章节到此就结束了,也希望大家可以
1)丢异步方法有个简单的调用(自然很简单)
2)温故而知新希望大家通过最后一个测试类能对线程池、Future、事件异步回调有个进一步了解。
最后谢谢大家
坚持写作1个月了,现在发现朋友的一次转发、关注是对本文的最大支持,鼓励下,转发支持一次,谢谢
更多信息可以咨询 @架构师速成记