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中异步编程的问题 * * 异步-同步 * 阻塞-无阻塞 * * 同步和异步的区别? 异步;同步 指的是被请求者 解析:被请求者(该事情的处理者)在处理完事情的时候的 ...
随机推荐
- 如何寻找决策最优解?熵权TOPSIS助你科学决策
熵权topsis是一种融合了熵值法与TOPSIS法的综合评价方法.熵值法是一种客观赋值法,可以减少主观赋值带来的偏差:而topsis法是一种常见的多目标决策分析方法,适用于多方案.多对象的对比研究,从 ...
- Java二进制和位运算,这一万字准能喂饱你
基础不牢,地动山摇.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众号[BAT的乌托 ...
- oeasy教你玩转linux010104灵魂之问whatis
灵魂之问whatis 回忆上节课 我们上次在系统里面乱转
- Unity3d流光效果
Material中纹理的属性都有Tiling和Offset,可以利用Offset做uv动画,从而完成各种有趣的动画,比如流光效果! 流过效果即通常一条高光光在物体上划过,模拟高光移动照射物体的效果,之 ...
- 初学WebGL引擎-BabylonJS:第0篇-起因
学习WebGL的BabylonJS是在一次偶然的情况下进行的,主要为了满足个人对全栈开发的欲望. 言归正传,下面开始简单说说相关过程 WebGL是什么?WebGL是基于html的客户端页面技术,基于h ...
- MySql密码的问题
由于长时间没使用过MySql了,也由于之前没有做笔记的习惯,晚上因为MySQL的密码问题导致数据库长时间没连上.纠结了这么久还是决定记录下来,毕竟安装的东西多了,这年头到处都是密码,加上时间一长,很容 ...
- 使用代码给Unity中的动画片段绑定回调函数
在制作动作游戏的时候,需要播放许多动画,同时还有个需求,那就是动画播放到一定时间时,给一个回调函数,好做对应的状态变更, 我查了一下,发现如果使用的是unity自带的动画系统,要做到这样的话,需要这样 ...
- Mybatis源码学习第七天(PageHelper分析)
其实我本来是不打算写这个PageHelper的,但是后来想了想,还是写了吧!现在市场用Mybatis的产品分页应该差不多都是用PageHelper来实现的,毕竟Mybatis的分页rowbound.. ...
- Sympy解方程-求极限-微分-积分-矩阵运算
简介 Sympy是一个Python的科学计算库,用一套强大的符号计算体系完成诸如多项式求值.求极限.解方程.求积分.微分方程.级数展开.矩阵运算等等计算问题.虽然Matlab的类似科学计算能力也很强大 ...
- docker下jira数据备份和还原注意路径
重点:jira页面上的备份与恢复页面的路径,跟我实际路径是有出入的,如果找不到就用find去搜下备份文件就知道怎么操作了 1.登录jira后,右上角的系统——左侧的导入与导出——选择里面的备份与恢复 ...