当前位置: 首页 > news >正文

Spring:@Async 注解和AsyncResult与CompletableFuture使用

@Async概述

Spring中用@Async注解标记的方法,称为异步方法,它会在调用方的当前线程之外的独立的线程中执行,

  • 其实就相当于我们自己new Thread(()-> System.out.println("hello world !"))这样在另一个线程中去执行相应的业务逻辑

异步方法实际的执行交给了 Spring 的 TaskExecutor 来完成。

@Async使用

  1. @Async注解如果用在类的方法上,则说明改方法是异步方法
  2. @Async注解如果用在类上,那么这个类所有的方法都是异步执行的
  3. @Async注解方法的类对象应该是Spring容器管理的bean对象
  4. 调用异步方法类上需要配置上注解@EnableAsync,或者是在启动类上加上@EnableAsync

@Async注意

  1. 默认情况下(@EnableAsync注解的mode=AdviceMode.PROXY),同一个类内部没有使用@Async注解修饰的方法调用@Async注解修饰的方法,是不会异步执行的
  2. 如果想实现类内部自调用也可以异步,则需要切换@EnableAsync注解的mode=AdviceMode.ASPECTJ
  3. 任意参数类型都是支持的,但是方法返回值必须是void或者Future类型

@Async代码示例

使用1代码实现:调用异步方法类上配置@EnableAsync

import org.springframework.scheduling.annotation.Async;public interface TestService {@Asyncvoid test();
}
import com.example.service.TestService;
import org.springframework.stereotype.Service;@Service
public class TestServiceImpl implements TestService {@Overridepublic void test() {//...}
}

调用异步方法的controller类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping(value = "/test")
@EnableAsync
public class TestContoller {@Autowiredprivate TestService testService;@GetMapping(value = "/testAsync")public void print() {testService.test();}
}

如果我们去除TestController上的@EnableAsync或者new 一个TestService对象(该对象没有加载进Spring的容器中),那么TestController中的print()方法都会同步执行,后台打印日志也可以看到只有一个线程在执行

使用2代码实现:在启动类上配置@EnableAsync

如果启动类上配置@EnableAsync,那么在上例代码中,便不需要再在Controller上面加上@EnableAsync这个注解

入口类增加了 @EnableAsync 注解,主要是为了扫描范围包下的所有 @Async 注解。

注意1代码实现:@Async没有生效

@Async 修饰test()方法,test2()方法不修饰

public interface TestService {@Asyncvoid test();void test2();
}
public class TestServiceImpl implements TestService{@Overridepublic void test() {//...}@Overridepublic void test2() {test();//自调用test()方法}
}

这种情况下“:test2()方法调用的test()方法并没有异步执行,只有一个线程

AsyncResult

Spring中提供了一个 Future 接口的子类:AsyncResult,所以我们可以返回 AsyncResult 类型的值。

AsyncResult是异步方式,异步主要用于调用的代码需要长时间运行,才能返回结果的时候,可以不阻塞调用者

public class AsyncResult<V> implements ListenableFuture<V> {private final V value;private final ExecutionException executionException;//...
}

AsyncResult实现了ListenableFuture接口,该对象内部有两个属性:返回值和异常信息。

public interface ListenableFuture<T> extends Future<T> {void addCallback(ListenableFutureCallback<? super T> var1);void addCallback(SuccessCallback<? super T> var1, FailureCallback var2);
}

AsyncResult代码示例

获取异步方法返回值的实现:返回String

public Future<String> test() throws Exception {log.info("开始做任务");long start = System.currentTimeMillis();Thread.sleep(1000);long end = System.currentTimeMillis();log.info("完成任务,耗时:" + (end - start) + "毫秒");return new AsyncResult<>("任务完成,耗时" + (end - start) + "毫秒");
}

返回自定义类型的话,在上面的Future里面的String改为对应的实体类

CompletableFuture

统计一下三个任务并发执行共耗时多少,这就需要等到上述三个函数都完成调动之后记录时间,并计算结果。

也可以使用CompletableFuture来返回异步调用的结果

  1. 通过CompletableFuture.allOf(task1, task2, task3).join()实现三个异步任务都结束之前的阻塞效果
  2. 三个任务都完成之后,根据结束时间 - 开始时间,计算出三个任务并发执行的总耗时。

CompletableFuture代码示例

@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("任务一完成");
}
@Test
public void test() throws Exception {long start = System.currentTimeMillis();CompletableFuture<String> task1 = asyncTasks.test();CompletableFuture<String> task2 = asyncTasks.test();CompletableFuture<String> task3 = asyncTasks.test();CompletableFuture.allOf(task1, task2, task3).join();long end = System.currentTimeMillis();log.info("任务全部完成,总耗时:" + (end - start) + "毫秒");
}

线程池配置

自行谷歌或百度,spring线程池配置,基本上很详细了

相关文章:

Spring:@Async 注解和AsyncResult与CompletableFuture使用

Async概述 Spring中用Async注解标记的方法&#xff0c;称为异步方法&#xff0c;它会在调用方的当前线程之外的独立的线程中执行&#xff0c; 其实就相当于我们自己new Thread(()-> System.out.println("hello world !"))这样在另一个线程中去执行相应的业务逻辑…...

tidb ptca,ptcp考证

PingCAP 认证 TiDB 数据库专员 V6 考试&#xff08;2023-02-23&#xff09;https://learn.pingcap.com/learner/exam-market/list?categoryPCTA PingCAP 认证 TiDB 数据库管理专家&#xff08;PCTP - DBA&#xff09;认证考试范围指引 - ☄️ 学习与认证 - TiDB 的问答社区:lo…...

关于用windows开发遇到的各种乌龙事件之node版本管理---nvm install node之后 npm 找不到的问题

友情提醒&#xff0c;开发最好用nvm控制node版本 nrm 控制镜像源&#xff0c;能少掉很多头发开发过程中技术迭代更新的时候最要老命的就是 历史项目的node版本没有记录&#xff0c;导致开启旧项目的时候就会报错。尤其是npm 升级到8.x.x以后&#xff0c;各种版本不兼容。 真…...

JMeter做UI自动化

插件安装搜插件selenium&#xff0c;安装添加config添加线程组右键线程组->添加->配置元件->jpgc - Chrome Driver Configoption和proxy不解释了添加Sampler右键线程组->添加->取样器->jpgc - WebDriver Samplerscript language 选择&#xff1a;JavaScript&…...

Kibana与Elasticsearch

下载与安装Kibanahttps://www.elastic.co/cn/downloads/kibanaKibana的版本与Elasticsearch的版本是一致的&#xff0c;使用方法也和Elasticsearch一致。由于我的英文不是特别好&#xff0c;我们找到config/kibana.yml末尾添加i18n.locale: "zh-CN" &#xff0c;汉化…...

[数据结构]:03-栈(C语言实现)

目录 前言 已完成内容 单链表实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-StackCommon.cpp 04-StackFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容&#xff0c;除其中使用到C引用外&#xff0c;全为C语言代码。使用C引用主要是为了简…...

1W+企业都在用的数字化管理秘籍,快收藏!

企业数字化&#xff0c;绕不开的话题。 随着国家相继出台各种举措助力中小企业数字化转型&#xff0c;积极推动产业数字化转型&#xff0c;培育数字经济新生态&#xff0c;企业想要谋生存&#xff0c;求发展&#xff0c;必然需要做好数字化转型和管理。 本篇文章想跟大家一起…...

多模态机器学习入门——文献阅读(一)Multimodal Machine Learning: A Survey and Taxonomy

文章目录说明论文阅读AbstractIntroductionIntroduction总结Applications&#xff1a;A Historical Perspective补充与总结3 MULTIMODAL REPRESENTATIONS总结Joint Repersentations&#xff08;1&#xff09;总结和附加(一)Joint Repersentations&#xff08;2&#xff09;总结…...

通过哲学家进餐问题学习线程间协作(代码实现以leetcode1226为例)

哲学家进餐问题(代码实现以leetcode1226为例)问题场景解决思路解决死锁问题代码实现cgo(代码实现以leetcode1226为例) 提到多线程和锁解决问题&#xff0c;就想到了os中哲学家进餐问题。 问题场景 回想该问题产生场景&#xff0c;五个哲学家共用一张圆桌&#xff0c;分别坐在…...

消息队列--Kafka

Kafka简介集群部署配置Kafka测试Kafka1.Kafka简介 数据缓冲队列。同时提高了可扩展性。具有峰值处理能力&#xff0c;使用消息队列能够使关键组件顶住突发的访问压力&#xff0c;而不会因为突发的超负荷的请求而完全崩溃。 Kafka是一个分布式、支持分区的&#xff08;partition…...

外盘国际期货:我国当代年轻人结婚逐年下降

我国当代年轻人 结婚现状结婚少了 结婚晚了 2013年后结婚人数逐年下降 结婚少了 离婚多了 结婚年龄越来越迟 以30岁为界线&#xff0c;30岁之后结婚占比逐年增加 2018 20-24岁&#xff1a;435.6万人 25-29岁&#xff1a;736.2万人 30-34岁&#xff1a;314.7万人 35-3…...

Ubuntu 22.04.2 发布,可更新至 Linux Kernel 5.19

Ubuntu 22.04 LTS (Jammy Jellyfish) Ubuntu 22.04.2 发布&#xff0c;可更新至 Linux Kernel 5.19 请访问原文链接&#xff1a;Ubuntu 22.04 LTS (Jammy Jellyfish)&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;www.sysin.org 发行说…...

论文阅读笔记——《室内服务机器人的实时场景分割算法》

一、主要工作 通过深度可分离卷积、膨胀卷积和通道注意力机制设计轻量级的高准确度特征提取模块。融合浅层特征与深层语义特征获得更丰富的图像特征。在NYUDv2和CamVid数据集上的MIoU分别达到72.7%和59.9%&#xff0c;模型的计算力为4.2GFLOPs&#xff0c;参数量为8.3Mb。 二…...

Hive学习——自定义函数UDFUDTF

目录 一、添加依赖 二、编写自定义UDF函数 (一)自定义首字母大写函数 1.java代码 2.hive中运行 (二)自定义字符串全部小写的函数 1.java代码 2.hive运行 (三)创建解析JSON字符串的函数 1.java代码 三、自定义编写UDTF函数 1.java编写 2.hive运行 虽然Hive中内置了…...

自学前端,你必须要掌握的3种定时任务

当你看到这篇博客的时候&#xff0c;一定会和狗哥结下不解之缘&#xff0c;因为狗哥的博客里不仅仅有代码&#xff0c;还有很多代码之外的东西&#xff0c;如果你可以看到最底部&#xff0c;看到投票环节&#xff0c;我相信你一定感觉到了&#xff0c;狗哥的真诚&#xff0c;狗…...

__stack_chk_fail问题分析

一、问题进程收到SIGABRT信号异常退出&#xff0c;异常调用栈显示__stack_chk_fail*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: Pico/A7H10/PICOA7H10:10/5.5.0/smartcm.1676912090:userdebug/dev-keys Revision: 0 ABI: arm64 Times…...

linux 查看当前系统用户

1.查看当前登录账号(whoami) whoami ---------------------- root2.查看当前账号信息(id) id --------------------------- uid0(root) gid0(root) groups0(root)3.查看/etc/passwd文件 可以看到每行记录对应着一个用户信息&#xff0c;每条记录 共7段 用 冒号: 拼接&#xf…...

AI算法创新赛-人车目标检测竞赛总结05

队伍&#xff1a;AI0000043 1. 算法方案 由于赛题同时要求速度和精度&#xff0c;所以我们优先考虑小模型&#xff0c;在保证模型速度的同时通过模型调优稳 定提升模型精度。此外&#xff0c;由于图片分辨率比较大&#xff0c;且数据集中小目标占比高&#xff0c;我们计划使用…...

CSS 浮动【快速掌握知识点】

目录 前言 一、设置浮动属性 二、确定浮动元素的宽度 三、清除浮动 总结&#xff1a; 前言 CSS浮动是一种布局技术&#xff0c;它允许元素浮动到其父元素的左侧或右侧&#xff0c;从而腾出空间给其他元素。 一、设置浮动属性 使用CSS float属性将元素设置为浮动。例如&…...

在做自动化测试前需要知道的

什么是自动化测试&#xff1f; 做测试好几年了&#xff0c;真正学习和实践自动化测试一年&#xff0c;自我感觉这一个年中收获许多。一直想动笔写一篇文章分享自动化测试实践中的一些经验。终于决定花点时间来做这件事儿。 首先理清自动化测试的概念&#xff0c;广义上来讲&a…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧

上周三&#xff0c;HubSpot宣布已构建与ChatGPT的深度集成&#xff0c;这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋&#xff0c;但同时也存在一些关于数据安全的担忧。 许多网络声音声称&#xff0c;这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

Vue 3 + WebSocket 实战:公司通知实时推送功能详解

&#x1f4e2; Vue 3 WebSocket 实战&#xff1a;公司通知实时推送功能详解 &#x1f4cc; 收藏 点赞 关注&#xff0c;项目中要用到推送功能时就不怕找不到了&#xff01; 实时通知是企业系统中常见的功能&#xff0c;比如&#xff1a;管理员发布通知后&#xff0c;所有用户…...