大家好,我是程序猿小马,沪漂一族!
写文章就是对于平时的总结以及大家共同学习进步,早日码出各自的梦想😊
来源:
委内瑞拉玻利瓦尔的安赫尔瀑布
文章目录
- 1、起因
- 2、简单入门
- 2.1 同步执行
- 2.2 异步执行
- 每日小结
1、起因
在日常开发中,我们的逻辑都是同步调用,顺序执行。在一些场景下,我们会希望异步调用,将和主线程关联度低的逻辑异步调用,以实现让主线程更快的执行完成,提升性能。例如说:记录用户访问日志到数据库,记录管理员操作日志到数据库中。
我们可能会想到多线程去解决这个问题,但springboot提供了更便捷的方式,接下来跟着小马去了解一下吧!
2、简单入门
2.1 同步执行
controller:
@RestController
@RequestMapping("/async")
@Slf4j
public class AsyncController {
@Autowired
private MySync mySync;
@GetMapping(value = "/test")
public void testAsync() throws InterruptedException {
long start = System.currentTimeMillis();
mySync.task1();
mySync.task2();
long end = System.currentTimeMillis();
System.out.println("执行整个接口消耗时间:" + (end - start) + "ms");
}
}
service:
@Service
public class MySyncImpl implements MySync {
/**
* 步骤一
*
* @throws InterruptedException
*/
public void task1() throws InterruptedException {
long start = System.currentTimeMillis();
Thread.sleep(3000);
long end = System.currentTimeMillis();
System.out.println("task1消耗的时间:" + (end - start) + "ms");
}
/**
* 步骤二
*
* @throws InterruptedException
*/
public void task2() throws InterruptedException {
long start = System.currentTimeMillis();
Thread.sleep(4000);
long end = System.currentTimeMillis();
System.out.println("task2消耗时间:" + (end - start) + "ms");
}
}
结果:
task1消耗的时间:3002ms
task2消耗时间:4005ms
执行整个接口消耗时间:7007ms
从这里我们可以看出整个接口执行完需要等步骤一和步骤二全部执行完才可以结束
2.2 异步执行
- 如果上文中的步骤一,步骤二对整个接口并没有影响,他们只负责记录日志或者别的不是很重要得内容时,如果同步得话,会非常得影响用户的使用感觉,这里就引出了我们的异步调用
首先:
- 在项目的启动类上添加@EnableAsync注解即可
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
try {
SpringApplication.run(Application.class, args);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Config配置类
@EnableAsync
@Configuration
public class AsyncConfig {
@Bean("batch")
public AsyncTaskExecutor asyncTaskExecutor() {
ThreadPoolTaskExecutor asyncTaskExecutor = new ThreadPoolTaskExecutor();
asyncTaskExecutor.setCorePoolSize(100);
asyncTaskExecutor.setMaxPoolSize(200);
asyncTaskExecutor.setQueueCapacity(1200);
asyncTaskExecutor.setThreadNamePrefix("wechat-async-task-thread-pool-");
asyncTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
asyncTaskExecutor.initialize();
return asyncTaskExecutor;
}
}
- 一般来说这种参数会配置到nacos中,这边使用注解注入进来,方便后面维护。
service:
@Async("batch")
public void task1() throws InterruptedException {
long start = System.currentTimeMillis();
Thread.sleep(3000);
long end = System.currentTimeMillis();
System.out.println("task1消耗的时间:" + (end - start) + "ms");
}
@Async("batch")
public void task2() throws InterruptedException {
long start = System.currentTimeMillis();
Thread.sleep(4000);
long end = System.currentTimeMillis();
System.out.println("task2消耗时间:" + (end - start) + "ms");
}
结果:
执行整个接口消耗时间:55ms
task1消耗的时间:3009ms
task2消耗时间:4011ms
异步就可以保证接口的返回速度,那些用户不关心的工作可以异步去执行,提高响应速度。
每日小结
- 异步是我们开发中要掌握的一项技术,今天讲解的是小马认为相对简单易懂的一种方式。
- 有能力的小伙伴可以动手敲一敲哦!
以上就是小马今天要发的内容,欢迎大家互相学习,共同进步,也可以在评论区互动哦!👇