@Async 是什么

void test() {
A();
B();
C();
}
复制代码

在没有Async的情况下,上面的方法是顺序执行的,也可以称为同步调用. B要在A执行完毕之后执行,C需要在B执行完毕之后执行,整个函数结束是在C执行完毕之后。

但是如果给B添加了@Async,执行顺序不变, 在执行完A之后,调用B,但是并不等待B完成,就执行C,C执行完毕之后,这个函数就执行完毕了.

在Java中,一般在处理类似的场景之时,都是基于创建独立的线程去完成相应的异步调用逻辑,通过主线程和不同的线程之间的执行流程,从而在启动独立的线程之后,主线程继续执行而不会产生停滞等待的情况。

什么时候需要添加@Async

根据业务需求,可以将暂时不需要获得处理的方法设置为@Async.

比如用户在前端点击完成了登录操作,这时候根据业务要求需要在登录成功之后进行埋点的处理.

其实埋点成功与否都不影响用户操作,这时候就可以将埋点方法设置为@Async.

个人认为此类任务通常有三个特征:

  1. 业务优先级低.
  2. 运行时间长,可能会造成卡顿.
  3. 返回结果暂时不立即处理,包括exception.

如何使用@Async

  1. 对当前Application添加@EnableAsync,当然也可以添加到Config,主要的是让Spring知道你有开启Async.
@EnableAsync
@SpringBootApplication
public class TestApplication { public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
复制代码
  1. 对当前方法添加Async
@Async
public void B() { }
复制代码
  1. 注意事项 对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() { }
}
复制代码
  1. 返回值只能为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中的异步编程的更多相关文章

  1. .Net中的异步编程总结

    一直以来很想梳理下我在开发过程中使用异步编程的心得和体会,但是由于我是APM异步编程模式的死忠,当TAP模式和TPL模式出现的时候我并未真正的去接纳这两种模式,所以导致我一直没有花太多心思去整理这两部 ...

  2. C#中的异步编程Async 和 Await

    谈到C#中的异步编程,离不开Async和Await关键字 谈到异步编程,首先我们就要明白到底什么是异步编程. 平时我们的编程一般都是同步编程,所谓同步编程的意思,和我们平时说的同时做几件事情完全不同. ...

  3. .NET中的异步编程——常见的错误和最佳实践

    在这篇文章中,我们将通过使用异步编程的一些最常见的错误来给你们一些参考. 背景 在之前的文章<.NET中的异步编程——动机和单元测试>中,我们开始分析.NET世界中的异步编程.在那篇文章中 ...

  4. javaScript中的异步编程模式

    1.事件模型 let button = document.getElementById("my-btn"); button.onclick = function(event) { ...

  5. Netty 中的异步编程 Future 和 Promise

    Netty 中大量 I/O 操作都是异步执行,本篇博文来聊聊 Netty 中的异步编程. Java Future 提供的异步模型 JDK 5 引入了 Future 模式.Future 接口是 Java ...

  6. 一文说通C#中的异步编程

    天天写,不一定就明白. 又及,前两天看了一个关于同步方法中调用异步方法的文章,里面有些概念不太正确,所以整理了这个文章.   一.同步和异步. 先说同步. 同步概念大家都很熟悉.在异步概念出来之前,我 ...

  7. 一文说通C#中的异步编程补遗

    前文写了关于C#中的异步编程.后台有无数人在讨论,很多人把异步和多线程混了. 文章在这儿:一文说通C#中的异步编程 所以,本文从体系的角度,再写一下这个异步编程.   一.C#中的异步编程演变 1. ...

  8. SpringBoot 如何实现异步编程,老鸟们都这么玩的!

    镜像下载.域名解析.时间同步请点击 阿里巴巴开源镜像站 首先我们来看看在Spring中为什么要使用异步编程,它能解决什么问题? 为什么要用异步框架,它解决什么问题? 在SpringBoot的日常开发中 ...

  9. promise 的基本概念 和如何解决js中的异步编程问题 对 promis 的 then all ctch 的分析 和 await async 的理解

    * promise承诺 * 解决js中异步编程的问题 * * 异步-同步 * 阻塞-无阻塞 * * 同步和异步的区别? 异步;同步 指的是被请求者 解析:被请求者(该事情的处理者)在处理完事情的时候的 ...

随机推荐

  1. Markdown - Typora 10分钟入门 - 精简归纳

    Markdown - Typora 10分钟入门 - 精简归纳 JERRY_Z. ~ 2020 / 8 / 22 转载请注明出处! 目录 Markdown - Typora 10分钟入门 - 精简归纳 ...

  2. Git的详细使用

    关于Git的详细使用,下面博主的博客写的非常的详细! 可以参考一下. https://blog.csdn.net/qq_19835247/article/details/104620042 人生需要准 ...

  3. SICP之应用序和正则序

    以一个题目来说明 (define (square x) (* x x)) (define (sum-squares x y) (+ (square x) (square y))) (define (f ...

  4. 前端测试框架 Jest

    前端测试工具一览 前端测试工具也和前端的框架一样纷繁复杂,其中常见的测试工具,大致可分为测试框架.断言库.测试覆盖率工具等几类.在正式开始本文之前,我们先来大致了解下它们: 测试框架 测试框架的作用是 ...

  5. Python的UI库

    https://github.com/realitix/vulkan https://github.com/swistakm/pyimgui https://wxpython.org

  6. 用 Spring Boot 和 MybatisPlus 快速构建项目

    自动生成 public class MPGenerator { public static void main(String[] args) { AutoGenerator autoGenerator ...

  7. 深入了解Netty【八】TCP拆包、粘包和解决方案

    1.TCP协议传输过程 TCP协议是面向流的协议,是流式的,没有业务上的分段,只会根据当前套接字缓冲区的情况进行拆包或者粘包: 发送端的字节流都会先传入缓冲区,再通过网络传入到接收端的缓冲区中,最终由 ...

  8. 【小白学PyTorch】7 最新版本torchvision.transforms常用API翻译与讲解

    文章来自:微信公众号[机器学习炼丹术].欢迎关注支持原创 也欢迎添加作者微信:cyx645016617. 参考目录: 目录 1 基本函数 1.1 Compose 1.2 RandomChoice 1. ...

  9. h5跳转微信公众号关注页面

    最近在做h5项目,有个需求是如果用户没有关注公众号,需要引导用户跳转至微信公众号关注页面 制作一个链接,点击该链接跳转到公众号关注页面. 1.从公众平台登进入公众号 2.点击开发>>开发者 ...

  10. 为商务办公赋能,TOM商务邮箱,塑造职场新形象

    转眼已至2020年,互联网的这10年发生了翻天覆地的改变.短视频红利崛起.人脸识别支付.AI智能机器人对话...很多产品从默默无闻到一夜崛起.而对于商务邮箱领域,邮箱已成为一种习惯,却往往忽略了它的点 ...