异步调用实践:Async,Future, TaskExecutor、EventListener
1. 异步调用概述
异步调用允许一个方法调用在不被当前线程阻塞的情况下继续执行,而调用者可以继续执行其他任务,直到异步操作完成。
在Spring Boot中,异步调用常用于提高应用的响应性和吞吐量,尤其是在处理长时间运行的任务时,如文件处理、数据库查询、网络请求等。
2. 异步调用注意点
- 线程安全性:确保异步方法中访问的共享资源是线程安全的。
- 异常处理:异步方法中的异常需要被捕获并适当处理,或者通过某种机制返回给调用者。
- 返回类型:异步方法的返回类型通常是
void、Future<T>或CompletableFuture<T>,以便调用者可以检查异步操作的结果或状态。 - 配置异步执行器:根据需要配置线程池大小等参数,以避免资源耗尽。
- 避免在相同类的方法中调用异步方法:因为这将绕过Spring的代理机制,导致异步调用不生效。
3. 异步调用场景
假设我们有一个在线书店应用,用户下单后需要发送订单确认邮件和更新库存。
这两个操作都是耗时的,我们希望它们异步执行,以便用户能够立即得到订单提交的反馈。
4. 具体实现
(1)@Async
首先,需要在Spring Boot中启用异步支持,在启动类上添加@EnableAsync注解。然后,在需要异步执行的方法上添加@Async注解。
@SpringBootApplication
@EnableAsync
public class BookstoreApplication {public static void main(String[] args) {SpringApplication.run(BookstoreApplication.class, args);}
}@Service
public class OrderService {@Asyncpublic void processOrder(Order order) {// 模拟发送邮件sendOrderConfirmationEmail(order);// 模拟更新库存updateStock(order);}// 实现sendOrderConfirmationEmail和updateStock方法
}
(2)CompletableFuture
CompletableFuture提供了更灵活的异步编程模型,允许你编写非阻塞代码,同时以声明方式处理异步完成时的结果。
@Service
public class OrderService {public CompletableFuture<Void> processOrderAsync(Order order) {CompletableFuture<Void> emailFuture = CompletableFuture.runAsync(() -> sendOrderConfirmationEmail(order));CompletableFuture<Void> stockFuture = CompletableFuture.runAsync(() -> updateStock(order));return CompletableFuture.allOf(emailFuture, stockFuture).thenApply(v -> null);}// 实现sendOrderConfirmationEmail和updateStock方法
}
(3)TaskExecutor
TaskExecutor是Spring提供的用于执行异步任务的接口。你可以通过配置一个TaskExecutor来管理线程池。
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(25);executor.initialize();return executor;}}@Service
public class OrderService {@Autowiredprivate TaskExecutor taskExecutor;public void processOrder(Order order) {taskExecutor.execute(() -> sendOrderConfirmationEmail(order));taskExecutor.execute(() -> updateStock(order));}// 实现sendOrderConfirmationEmail和updateStock方法
}
(4)@EventListener
虽然@EventListener主要用于事件监听,但你可以结合异步任务来监听特定事件(如订单创建事件),并异步处理。
@Component
public class OrderEventListener {@Async@EventListenerpublic void handleOrderCreatedEvent(OrderCreatedEvent event) {Order order = event.getOrder();sendOrderConfirmationEmail(order);updateStock(order);}// 实现sendOrderConfirmationEmail和updateStock方法
}// 假设你有一个OrderCreatedEvent类
public class OrderCreatedEvent extends ApplicationEvent {private Order order;public OrderCreatedEvent(Object source, Order order) {super(source);this.order = order;}// getter和setter
}
5. 总结
在Spring Boot中,实现异步调用可以通过多种方式,包括@Async注解、CompletableFuture、自定义TaskExecutor以及结合@EventListener进行异步事件处理。
每种方式都有其适用场景和优缺点,开发者应根据实际需求选择最合适的方法。
同时,使用异步调用时需要注意线程安全、异常处理以及合理配置异步。
相关文章:
异步调用实践:Async,Future, TaskExecutor、EventListener
1. 异步调用概述 异步调用允许一个方法调用在不被当前线程阻塞的情况下继续执行,而调用者可以继续执行其他任务,直到异步操作完成。 在Spring Boot中,异步调用常用于提高应用的响应性和吞吐量,尤其是在处理长时间运行的任务时&a…...
Flask 异常处理
Flask 异常处理 使用 app.errorhandler 装饰器使用 app.handle_exception 装饰器使用 register_error_handler调试模式总结 在 Flask 应用中,异常处理是一个非常重要的部分,它可以帮助你管理运行时错误,提供友好的错误页面,以及记…...
【海思SS626 | 内存管理】海思芯片的OS内存、MMZ内存设置
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…...
linux crontab没有按照规则执行排查
配置了cron规则,但是一段时间后任务没有按预期执行,记录一次修复过程 检查crond服务 systemctl status crond规则正常 crontab -l脚本有执行权限 查看日志 第一种:journalctl journalctl -u crond | grep 03:00 -C 3-u 指定crond.serv…...
Cloudflare的D1使用技巧
总文档:https://developers.cloudflare.com/workers/wrangler/commands/#d1查询某个数据库中哪些命令占用资源最大: To find top 10 queries by execution count: npx wrangler d1 insights <database_name> --sort-typesum --sort-bycount --co…...
解决端口号被占用问题
第一种: 最简单有效的方法,重启一下电脑,占用此端口的程序就会释放端口。 第二种: 使用命令找到占用端口的程序,把它关闭。 1、打开运行窗口输入:CMD ,进入命令窗口。 2、输入:n…...
如何在linux上部署zabbix监控工具
<1>搭建服务机 1)首先我们先执行 sed -i s/SELINUXenforcing/SELINUXdisabled/ /etc/selinux/config #然后我们再把防火墙开机自启关掉 马上生效 systemctl disable --now firewalld 2)我们获得rpm包 rpm -Uvh https://mirrors.aliyun.com/…...
vulnhub系列:sp eric
vulnhub系列:sp eric 靶机下载 一、信息收集 nmap扫描存活,根据mac地址寻找IP nmap 192.168.23.0/24nmap扫描端口,开放端口:22、80 nmap 192.168.23.189 -p- -A -sV -Pndirb 扫描目录,.git 源码,admin…...
JVM二:JVM类加载机制
目录 前言 1.什么是类加载? 2.类加载整体流程 3.一个类什么时候被加载? 4.双亲委派模型 4.1 JVM默认提供了三个类加载器 4.1.1 BootstrapClassLoader 4.1.2 ExtensionClassLoader 4.1.3 ApplicationClassLoader 4.2 破坏双亲委派模型 前言 在上一篇文章中…...
对于springboot无法连接redis解决方案
对于springboot无法连接redis解决方案 一、测试是否能在本地应用上访问到你的redis(如果是部署在linux上的话)1. 开启telnet功能2. 开始测试端口是否能访问到(适用于所有,包括MQ)3. 开放6379端口4. 看spring的配置文件…...
关于android中的各种尺寸与计算
--张学友《心如刀割》很好听 先说几个术语: Screen size(屏幕尺寸): 指的是手机实际的物理尺寸,比如常用的2.8英寸,3.2英寸,3.5英寸,3.7英寸 摩托罗拉milestone手机是3.7英寸 Aspect Ratio(宽高比率)&am…...
MySQL避免索引失效的方法详细介绍
避免索引失效 在MySQL中,索引是帮助MySQL高效获取数据的数据结构。它就像一本书的目录,通过索引可以快速定位到数据的具体位置,从而减少对数据库的扫描量,提高查询速度。索引可以存储在表中的一个或多个列上,创建索引…...
【Java】深入了解 Java 的 charAt() 方法
我最爱的那首歌最爱的angel 我到什么时候才能遇见我的angel 我最爱的那首歌最爱的angel 我不是王子也会拥有我的angel 🎵 张杰《云中的angel》 在 Java 编程中,字符串(String)是我们经常处理的数据类型之一。…...
Linux 下 ETCD 安装、配置与命令使用总结
大家好,我是程序员小羊! 前言: Linux 下 ETCD 安装、配置与命令使用总结 ETCD 是一个分布式键值存储系统,广泛用于服务发现、分布式锁、配置管理等场景,特别是在 Kubernetes 集群中发挥着至关重要的作用。ETCD 的高…...
C++笔试练习笔记【7】:力扣 91. 解码方法 动态规划练习
文章目录 题目题目分析思路解法正常解法优化解法 题目 题目链接:力扣 91. 解码方法 备用链接:https://leetcode.cn/problems/decode-ways/description/ 题目分析 1.首先我们知道题目给定A~Z编码为1 ~26 ,而数字十一字符串的形式给出所以…...
【antd】antd3的表单校验不提示报错信息
描述 不是网上所谓的自定义校验方法的问题。 今天在写一个antd3的业务的时候,封装一个组件,把校验和请求事件放在一个方法里面,用回调或者promise进行异步处理。 发现原因是在校验错误的判断,进行callback之后,页面…...
Game AI ——游戏人工智能(逻辑及剧情生成)
一、Game AI 的介绍 "Game AI"(游戏人工智能)通常指的是在电子游戏中使用的各种人工智能技术和算法,用于控制游戏中的非玩家角色(NPC)、敌人、队友等,以及为玩家提供有挑战性的对手或有趣的互动…...
算法基础知识——核函数
简介:个人学习分享,如有错误,欢迎批评指正 核函数(Kernel Function)是机器学习中一种重要的工具,特别是在支持向量机(SVM)、核岭回归、核主成分分析(KPCA)等核…...
安卓xml乱码/加密转换:abx2xml和xml2abx使用及源码介绍
背景: 上一篇文章 android系统中data下的xml乱码无法查看问题剖析及解决方法 发布后,想要寻找一个可以直接把二进制xml和普通xml进行相互转换的,当时还写了相关的方案,但是当时没有找到现成的开源工具,后来经过相关粉…...
slice 截取
JavaScript中的一个数组方法。然而,在Vue 3的应用开发中,slice 方法经常被用于处理数组数据,特别是在需要实现分页、数据截取或数据展示等场景时。 slice 方法的基本用法 slice() 方法返回一个新的数组对象,这一对象是一个由 be…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
