在Spring Boot中使用@Async实现一个异步调用

在使用异步注解之前,我们需要先了解,什么是异步调用?

异步调用对应的事同步调用,同步调用是值程序按照我们定义的顺序依次执行,每一行程序都必须等待上一行的程序执行完成之后才执行,而异步是指在顺序执行的时候,不等待异步调用的语句返回结果就执行后面的程序,例如,我们常常进行对报表的导出,因为数据导出需要时间,为了避免用户在界面等待时间过长,我们就会采用异步进行导出。

我们来对比一下同步导出和异步导出的案例:

@Slf4j
@Component
public class AsyncTasks {

    public static Random random = new Random();

    //@Async
    public CompletableFuture<String> doTaskOne() throws Exception {
        log.info("开始做任务一");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("完成任务一,耗时:" + (end - start) + "毫秒");
        return CompletableFuture.completedFuture("任务一完成");
    }

    //@Async
    public CompletableFuture<String> doTaskTwo() throws Exception {
        log.info("开始做任务二");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("完成任务二,耗时:" + (end - start) + "毫秒");
        return CompletableFuture.completedFuture("任务二完成");
    }

    //@Async
    public CompletableFuture<String>  doTaskThree() throws Exception {
        log.info("开始做任务三");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("完成任务三,耗时:" + (end - start) + "毫秒");
        return CompletableFuture.completedFuture("任务三完成");
    }

}

在我们的测试类中执行三个函数方法,

@Slf4j
@SpringBootTest
public class ApplicationTests {

    @Autowired
    private AsyncTasks asyncTasks;

    @Test
    public void test() throws Exception {
        asyncTasks.doTaskOne();
        asyncTasks.doTaskTwo();
        asyncTasks.doTaskThree();
    }

}

异步调用:

@Slf4j
@Component
public class AsyncTasks {

    public static Random random = new Random();

    @Async
    public CompletableFuture<String> doTaskOne() throws Exception {
        log.info("开始做任务一");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("完成任务一,耗时:" + (end - start) + "毫秒");
        return CompletableFuture.completedFuture("任务一完成");
    }

    @Async
    public CompletableFuture<String> doTaskTwo() throws Exception {
        log.info("开始做任务二");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("完成任务二,耗时:" + (end - start) + "毫秒");
        return CompletableFuture.completedFuture("任务二完成");
    }

    @Async
    public CompletableFuture<String>  doTaskThree() throws Exception {
        log.info("开始做任务三");
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("完成任务三,耗时:" + (end - start) + "毫秒");
        return CompletableFuture.completedFuture("任务三完成");
    }

}
@Slf4j
@SpringBootTest
public class ApplicationTests {

    @Autowired
    private AsyncTasks asyncTasks;

    @Test
    public void test() throws Exception {
        long start = System.currentTimeMillis();

        CompletableFuture<String> task1 = asyncTasks.doTaskOne();
        CompletableFuture<String> task2 = asyncTasks.doTaskTwo();
        CompletableFuture<String> task3 = asyncTasks.doTaskThree();

        CompletableFuture.allOf(task1, task2, task3).join();

        long end = System.currentTimeMillis();

        log.info("任务全部完成,总耗时:" + (end - start) + "毫秒");
    }

}

注意,异步调用的结果是随机的,你的结果和我这边的结果不一样很正常。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/211162.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

动态规划------方法汇总

核心&#xff1a; 状态定义 状态转移方程 启发思路&#xff08;两种情况&#xff09;&#xff1a;选 或 不选 / 选哪个 DP三步&#xff1a;先写回溯&#xff0c;时间复杂度 指数级别&#xff1b;递归的过程中会重复计算&#xff0c;要保存计算结果&#xff0c;递归搜索…

uniapp是否可以用elementUI等前端UI库、使用步骤以及需要注意的问题

文章目录 uniapp是否可以用elementUI等前端UI库使用方法和步骤问题如何解决 uniapp是否可以用elementUI等前端UI库 在PC端开发uniapp&#xff0c;可以用elementUI&#xff0c;因为elementUI就是PC端的。 在使用uniapp&#xff0c;选择vue2.0时&#xff0c;实测可以用nodejs16的…

Linux部署HDFS集群

&#xff08;一&#xff09;VMware虚拟机中部署 ps、其中node1、node2、node3替换为自己相应节点的IP地址&#xff0c;或者host文件中配置过的主机名&#xff0c;或者看前置准备 或者查看前置准备&#xff1a;Linux部署HDFS集群前置准备 1.下载压缩包 https://www.apache.or…

管理类联考-性质

性质 ——性质—— 一、是什么 &#xff08;1&#xff09;本质&#xff1a;判断一定范围内的对象是否具备某个性质的命题就是性质命题&#xff08;直言命题&#xff09;。直言命题是断定事物/对象是否具有某种性质的命题。直言命题在结构上由主项、谓项、联项和量项组成。 &am…

对Spring框架的一些总结

对Spring框架的一些总结 在文章开头我真心推荐大家一个优秀的编程老师&#xff1a;孙帅老师(孙哥suns)&#xff0c;孙帅老师在哔哩哔哩的Spring5教学视频时长接近33个小时&#xff0c;从0基础到一步一步手把手的教你抽丝剥茧分析Spring框架的所有知识&#xff0c;孙帅老师的教…

打印元素绘制协议Java实现

我一直提倡的面向接口和约定编程&#xff0c;而打印元素绘制协议一直是我推荐的打印实现方式&#xff0c;我以前只是强调按打印元素绘制协议输出数据就行了&#xff0c;有实现程序按协议控制打印&#xff0c;说是可以用任何语言实现客户端程序而不影响打印业务&#xff0c;那么…

《opencv实用探索·八》图像模糊之均值滤波简单理解

1、前言 什么是噪声&#xff1f; 该像素与周围像素的差别非常大&#xff0c;导致从视觉上就能看出该像素无法与周围像素组成可识别的图像信息&#xff0c;降低了整个图像的质量。这种“格格不入”的像素就被称为图像的噪声。如果图像中的噪声都是随机的纯黑像素或者纯白像素&am…

【动态规划】LeetCode-91.解码方法

&#x1f388;算法那些事专栏说明&#xff1a;这是一个记录刷题日常的专栏&#xff0c;每个文章标题前都会写明这道题使用的算法。专栏每日计划至少更新1道题目&#xff0c;在这立下Flag&#x1f6a9; &#x1f3e0;个人主页&#xff1a;Jammingpro &#x1f4d5;专栏链接&…

leetcode-160-相交链表(C语言实现)

题目&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;…

Leetcode226. 翻转二叉树

文章目录 题目介绍题目分析解题思路边界条件&#xff1a;节点为空时返回空子问题&#xff1a;交换左右子节点 整体代码 题目介绍 题目分析 题目要求我们将树中每个节点的左右子节点全部交换,最后返回交换后的树的根节点。 解题思路 这题是比较常见的递归&#xff0c;直接找边…

LangChain 18 LangSmith监控评估Agent并创建对应的数据库

LangChain系列文章 LangChain 实现给动物取名字&#xff0c;LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字LangChain 3使用Agent访问Wikipedia和llm-math计算狗的平均年龄LangChain 4用向量数据库Faiss存储&#xff0c;读取YouTube的视频文本搜索I…

最多不一定最好,只有适合的才是最好的!电脑的内存多大才是合理的

RAM&#xff0c;或称随机存取存储器&#xff0c;是最好的笔记本电脑和最好的电脑最重要的组成部分之一。硬盘驱动器&#xff08;HDD&#xff09;或固态驱动器&#xff08;SSD&#xff09;存储可以被视为电脑的长期内存&#xff0c;内存是其短期内存。内存可以跟踪后台运行的应用…

背包9讲系列2-完全背包问题

一、前言 又到周末了&#xff0c;这几天可以腾出时间来把背包系列的其他内容好好肝一肝&#xff0c;本次介绍的是完全背包问题&#xff0c;之前的系列内容请查看&#xff1a; 背包9讲系列1-01背包问题 二、完全背包 2.1 问题描述 有n个物品和一个容量为capacity的背包&…

误用STM32串口发送标志位 “USART_FLAG_TXE” “USART_FLAG_TC”造成的BUG

当你使用串口发送数据时是否出现过这样的情况&#xff1a; 1.发送时第一个字节丢失。 2.发送时出现莫名的字节丢失。 3.各种情况字节丢失。 1.先了解一下串口发送的流程图&#xff08;手动描绘&#xff09;&#xff1a; 可以假想USART_FLAG_TXE是用于检测"弹仓"&…

C++11——initializer_list

initializer_list的简介 initializer_list是C11新出的一个类型&#xff0c;正如类型的简介所说&#xff0c;initializer_list一般用于作为构造函数的参数&#xff0c;来让我们更方便赋值 但是光看这些&#xff0c;我们还是不知道initializer_list到底是个什么类型&#xff0c;…

关于标准库中的vector - (涉及迭代器失效,深浅拷贝,构造函数,内置类型构造函数,匿名对象)

目录 关于vector vector中的常见接口 vector常见接口的实现 迭代器失效 关于深浅拷贝 关于vector 关于vector的文档介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元…

零售数字化“逆熵”的6项原则和8种能力建设|ShopeX徐礼昭

作者&#xff1a;徐礼昭 来源&#xff1a;《三体零售逆熵法则》节选 旧的规则与秩序被打破&#xff0c;无序成为常态 新时代洪流裹挟冲击着传统零售 无序带来的“熵增”侵蚀企业生命 所有人都在不确定性中寻找确定 数字化如何助力企业铸就「反熵增」神器&#xff1f; 如何…

【交换排序 简单选择排序 堆排序 归并排序】

文章目录 交换排序简单选择排序堆排序归并排序 交换排序 冒泡排序的算法分析&#xff1a; 冒泡排序最好的时间复杂度是O&#xff08;n&#xff09;冒泡排序最好的时间复杂度是O&#xff08;n平方&#xff09;冒泡排序平均时间复杂度为O&#xff08;n的平方&#xff09;冒泡排…

spring boot定时器实现定时同步数据

文章目录 目录 文章目录 前言 一、依赖和目录结构 二、使用步骤 2.1 两个数据源的不同引用配置 2.2 对应的mapper 2.3 定时任务处理 总结 前言 一、依赖和目录结构 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifa…

无线物理层安全学习

文章目录 3.17到3.203.85到3.88 3.17到3.20 3.85到3.88