SpringBoot中的异步编程
@Async 是什么
void test() {
A();
B();
C();
}
复制代码
在没有Async的情况下,上面的方法是顺序执行的,也可以称为同步调用. B要在A执行完毕之后执行,C需要在B执行完毕之后执行,整个函数结束是在C执行完毕之后。
但是如果给B添加了@Async,执行顺序不变, 在执行完A之后,调用B,但是并不等待B完成,就执行C,C执行完毕之后,这个函数就执行完毕了.
在Java中,一般在处理类似的场景之时,都是基于创建独立的线程去完成相应的异步调用逻辑,通过主线程和不同的线程之间的执行流程,从而在启动独立的线程之后,主线程继续执行而不会产生停滞等待的情况。
什么时候需要添加@Async
根据业务需求,可以将暂时不需要获得处理的方法设置为@Async.
比如用户在前端点击完成了登录操作,这时候根据业务要求需要在登录成功之后进行埋点的处理.
其实埋点成功与否都不影响用户操作,这时候就可以将埋点方法设置为@Async.
个人认为此类任务通常有三个特征:
- 业务优先级低.
- 运行时间长,可能会造成卡顿.
- 返回结果暂时不立即处理,包括exception.
如何使用@Async
- 对当前Application添加@EnableAsync,当然也可以添加到Config,主要的是让Spring知道你有开启Async.
@EnableAsync
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
复制代码
- 对当前方法添加Async
@Async
public void B() {
}
复制代码
- 注意事项 对Static方法修饰无效! 调用与被修饰方法不能写在同一个函数中。
比如:
class Test {
public void A() {
B(); // 这时候不会触发Async
}
@Async
public void B() {
}
}
复制代码
所以需要拆开调用:
class Test {
public void A() {
TestB testB = new TestB();
testB.B();
}
}
class TestB {
@Async
public void B() {
}
}
复制代码
- 返回值只能为Future或者Void, Future的使用方式.
@Async
public Future<String> asyncMethod() {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
System.out.println("StartTime - " + Thread.currentThread().getName() + df.format(new Date()));
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("EndTime - " + Thread.currentThread().getName() + df.format(new Date()));
return new AsyncResult<String>("hello world!");
}
@Test
public void contextLoads() {
Future<String> result1 = test.asyncMethod();
Future<String> result2 = test.asyncMethod();
Future<String> result3 = test.asyncMethod();
while (!result1.isDone() || !result2.isDone() || !result3.isDone()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
复制代码
自定义线程池
@Configuration
public class TaskConfiguration {
@Bean("taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10); // 线程池创建时候初始化的线程数
executor.setMaxPoolSize(20); // 线程池最大的线程数,只有在缓冲队列满了之后,才会申请超过核心线程数的线程
executor.setQueueCapacity(200); // 缓冲任务队列的大小
executor.setKeepAliveSeconds(60); // 允许线程的空闲时间,超过会被销毁
executor.setThreadNamePrefix("custom-prefix-");// 线程的前缀
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 对拒绝任务的处理策略
return executor;
}
}
//定义之后在Async中指定
@Async("taskExecutor")
......
复制代码
由于在应用关闭的时候异步任务还在执行,导致类似 数据库连接池 这样的对象一并被 销毁了,当 异步任务 中对 数据库 进行操作就会出错。
setWaitForTasksToCompleteOnShutdown(true): 该方法用来设置 线程池关闭 的时候 等待 所有任务都完成后,再继续 销毁 其他的 Bean,这样这些 异步任务 的 销毁 就会先于 数据库连接池对象 的销毁。 setAwaitTerminationSeconds(60): 该方法用来设置线程池中 任务的等待时间,如果超过这个时间还没有销毁就 强制销毁,以确保应用最后能够被关闭,而不是阻塞住。
SpringBoot中的异步编程的更多相关文章
- .Net中的异步编程总结
一直以来很想梳理下我在开发过程中使用异步编程的心得和体会,但是由于我是APM异步编程模式的死忠,当TAP模式和TPL模式出现的时候我并未真正的去接纳这两种模式,所以导致我一直没有花太多心思去整理这两部 ...
- C#中的异步编程Async 和 Await
谈到C#中的异步编程,离不开Async和Await关键字 谈到异步编程,首先我们就要明白到底什么是异步编程. 平时我们的编程一般都是同步编程,所谓同步编程的意思,和我们平时说的同时做几件事情完全不同. ...
- .NET中的异步编程——常见的错误和最佳实践
在这篇文章中,我们将通过使用异步编程的一些最常见的错误来给你们一些参考. 背景 在之前的文章<.NET中的异步编程——动机和单元测试>中,我们开始分析.NET世界中的异步编程.在那篇文章中 ...
- javaScript中的异步编程模式
1.事件模型 let button = document.getElementById("my-btn"); button.onclick = function(event) { ...
- Netty 中的异步编程 Future 和 Promise
Netty 中大量 I/O 操作都是异步执行,本篇博文来聊聊 Netty 中的异步编程. Java Future 提供的异步模型 JDK 5 引入了 Future 模式.Future 接口是 Java ...
- 一文说通C#中的异步编程
天天写,不一定就明白. 又及,前两天看了一个关于同步方法中调用异步方法的文章,里面有些概念不太正确,所以整理了这个文章. 一.同步和异步. 先说同步. 同步概念大家都很熟悉.在异步概念出来之前,我 ...
- 一文说通C#中的异步编程补遗
前文写了关于C#中的异步编程.后台有无数人在讨论,很多人把异步和多线程混了. 文章在这儿:一文说通C#中的异步编程 所以,本文从体系的角度,再写一下这个异步编程. 一.C#中的异步编程演变 1. ...
- SpringBoot 如何实现异步编程,老鸟们都这么玩的!
镜像下载.域名解析.时间同步请点击 阿里巴巴开源镜像站 首先我们来看看在Spring中为什么要使用异步编程,它能解决什么问题? 为什么要用异步框架,它解决什么问题? 在SpringBoot的日常开发中 ...
- promise 的基本概念 和如何解决js中的异步编程问题 对 promis 的 then all ctch 的分析 和 await async 的理解
* promise承诺 * 解决js中异步编程的问题 * * 异步-同步 * 阻塞-无阻塞 * * 同步和异步的区别? 异步;同步 指的是被请求者 解析:被请求者(该事情的处理者)在处理完事情的时候的 ...
随机推荐
- docker run 创建容器
docker run常用命令 docker run :创建一个新的容器并运行一个命令 - 语法:docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 1.OPTI ...
- CODING DevOps 代码质量实战系列第一课:代码规范与 Git Flow
讲师介绍 杨周 CODING DevOps 架构师 CODING 布道师 连续创业者.DIY/Linux 玩家.知乎小 V,曾在创新工场.百度担任后端开发.十余年一线研发和带队经验,经历了 ToB.T ...
- EventLoop-浏览器篇2
最近又碰到了event loop问题,之前研究的实在是浅显(https://www.cnblogs.com/zx0423/p/12641637.html)所以今天主要讲述promise的链式调用,as ...
- 火狐Firefox 52.90版是最后一个支持WinXP和Vista的版本
Firefox 52.90版是最后一个支持 Windows XP 和 Windows Vista 的升级版.(参考:https://support.mozilla.org/zh-CN/kb/firef ...
- 一键洞察全量SQL ,远离性能异常
随着云数据库业务规模不断扩大,用户对安全审计.性能智能分析等高级特性的要求越来越高.如何安全审计SQL?如何快速定位性能异常?如何保护数据库安全?是每个云厂商不得不思考的问题. 华为云DAS服务提供的 ...
- js中的各种常用方法(持续更新中。。。)
我看到常用的就写上去,如果你们有,可以在评论上发表,我再把它补充到我的随笔中 some() var ages = [3, 10, 18, 20]; function checkAdult(age) { ...
- Typescript | Vue3源码系列
TypeScript 是开源的,TypeScript 是 JavaScript 的类型的超集,它可以编译成纯 JavaScript.编译出来的 JavaScript 可以运行在任何浏览器上.TypeS ...
- Android开发之最火的开源框架之一Xutils2详解(摘自开源作者官方介绍详解)
此框架说实话还是挺不错的,挺好用的,功能多,所以我也用过. 由于CSDN博客写的字数有限制,所以全文的用法打包成了markdown 文件,因为markdown真的太还用了. 全文下载地址为: http ...
- SpringCloud实战 | 第五篇:SpringCloud整合OpenFeign实现微服务之间的调用
一. 前言 微服务实战系列是基于开源微服务项目 有来商城youlai-mall 版本升级为背景来开展的,本篇则是讲述SpringCloud整合OpenFeign实现微服务之间的相互调用,有兴趣的朋友可 ...
- sort(桶排序+hash)
题目链接:https://cn.vjudge.net/problem/HDU-1425 注意是多组输入 代码: #include<cstdio> #include<iostream& ...