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

异步调用实践:Async,Future, TaskExecutor、EventListener

1. 异步调用概述

异步调用允许一个方法调用在不被当前线程阻塞的情况下继续执行,而调用者可以继续执行其他任务,直到异步操作完成。

在Spring Boot中,异步调用常用于提高应用的响应性和吞吐量,尤其是在处理长时间运行的任务时,如文件处理、数据库查询、网络请求等。

2. 异步调用注意点

  • 线程安全性:确保异步方法中访问的共享资源是线程安全的。
  • 异常处理:异步方法中的异常需要被捕获并适当处理,或者通过某种机制返回给调用者。
  • 返回类型:异步方法的返回类型通常是voidFuture<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. 异步调用概述 异步调用允许一个方法调用在不被当前线程阻塞的情况下继续执行&#xff0c;而调用者可以继续执行其他任务&#xff0c;直到异步操作完成。 在Spring Boot中&#xff0c;异步调用常用于提高应用的响应性和吞吐量&#xff0c;尤其是在处理长时间运行的任务时&a…...

Flask 异常处理

Flask 异常处理 使用 app.errorhandler 装饰器使用 app.handle_exception 装饰器使用 register_error_handler调试模式总结 在 Flask 应用中&#xff0c;异常处理是一个非常重要的部分&#xff0c;它可以帮助你管理运行时错误&#xff0c;提供友好的错误页面&#xff0c;以及记…...

【海思SS626 | 内存管理】海思芯片的OS内存、MMZ内存设置

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…...

linux crontab没有按照规则执行排查

配置了cron规则&#xff0c;但是一段时间后任务没有按预期执行&#xff0c;记录一次修复过程 检查crond服务 systemctl status crond规则正常 crontab -l脚本有执行权限 查看日志 第一种&#xff1a;journalctl journalctl -u crond | grep 03:00 -C 3-u 指定crond.serv…...

Cloudflare的D1使用技巧

总文档&#xff1a;https://developers.cloudflare.com/workers/wrangler/commands/#d1查询某个数据库中哪些命令占用资源最大&#xff1a; To find top 10 queries by execution count: npx wrangler d1 insights <database_name> --sort-typesum --sort-bycount --co…...

解决端口号被占用问题

第一种&#xff1a; 最简单有效的方法&#xff0c;重启一下电脑&#xff0c;占用此端口的程序就会释放端口。 第二种&#xff1a; 使用命令找到占用端口的程序&#xff0c;把它关闭。 1、打开运行窗口输入&#xff1a;CMD &#xff0c;进入命令窗口。 2、输入&#xff1a;n…...

如何在linux上部署zabbix监控工具

<1>搭建服务机 1&#xff09;首先我们先执行 sed -i s/SELINUXenforcing/SELINUXdisabled/ /etc/selinux/config ​ #然后我们再把防火墙开机自启关掉 马上生效 systemctl disable --now firewalld 2&#xff09;我们获得rpm包 rpm -Uvh https://mirrors.aliyun.com/…...

vulnhub系列:sp eric

vulnhub系列&#xff1a;sp eric 靶机下载 一、信息收集 nmap扫描存活&#xff0c;根据mac地址寻找IP nmap 192.168.23.0/24nmap扫描端口&#xff0c;开放端口&#xff1a;22、80 nmap 192.168.23.189 -p- -A -sV -Pndirb 扫描目录&#xff0c;.git 源码&#xff0c;admin…...

JVM二:JVM类加载机制

目录 前言 1.什么是类加载? 2.类加载整体流程 3.一个类什么时候被加载? 4.双亲委派模型 4.1 JVM默认提供了三个类加载器 4.1.1 BootstrapClassLoader 4.1.2 ExtensionClassLoader 4.1.3 ApplicationClassLoader 4.2 破坏双亲委派模型 前言 在上一篇文章中&#xf…...

对于springboot无法连接redis解决方案

对于springboot无法连接redis解决方案 一、测试是否能在本地应用上访问到你的redis&#xff08;如果是部署在linux上的话&#xff09;1. 开启telnet功能2. 开始测试端口是否能访问到&#xff08;适用于所有&#xff0c;包括MQ&#xff09;3. 开放6379端口4. 看spring的配置文件…...

关于android中的各种尺寸与计算

--张学友《心如刀割》很好听 先说几个术语&#xff1a; Screen size(屏幕尺寸)&#xff1a; 指的是手机实际的物理尺寸&#xff0c;比如常用的2.8英寸&#xff0c;3.2英寸&#xff0c;3.5英寸&#xff0c;3.7英寸 摩托罗拉milestone手机是3.7英寸 Aspect Ratio(宽高比率)&am…...

MySQL避免索引失效的方法详细介绍

避免索引失效 在MySQL中&#xff0c;索引是帮助MySQL高效获取数据的数据结构。它就像一本书的目录&#xff0c;通过索引可以快速定位到数据的具体位置&#xff0c;从而减少对数据库的扫描量&#xff0c;提高查询速度。索引可以存储在表中的一个或多个列上&#xff0c;创建索引…...

【Java】深入了解 Java 的 charAt() 方法

我最爱的那首歌最爱的angel 我到什么时候才能遇见我的angel 我最爱的那首歌最爱的angel 我不是王子也会拥有我的angel &#x1f3b5; 张杰《云中的angel》 在 Java 编程中&#xff0c;字符串&#xff08;String&#xff09;是我们经常处理的数据类型之一。…...

Linux 下 ETCD 安装、配置与命令使用总结

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; Linux 下 ETCD 安装、配置与命令使用总结 ETCD 是一个分布式键值存储系统&#xff0c;广泛用于服务发现、分布式锁、配置管理等场景&#xff0c;特别是在 Kubernetes 集群中发挥着至关重要的作用。ETCD 的高…...

C++笔试练习笔记【7】:力扣 91. 解码方法 动态规划练习

文章目录 题目题目分析思路解法正常解法优化解法 题目 题目链接&#xff1a;力扣 91. 解码方法 备用链接&#xff1a;https://leetcode.cn/problems/decode-ways/description/ 题目分析 1.首先我们知道题目给定A~Z编码为1 ~26 &#xff0c;而数字十一字符串的形式给出所以…...

【antd】antd3的表单校验不提示报错信息

描述 不是网上所谓的自定义校验方法的问题。 今天在写一个antd3的业务的时候&#xff0c;封装一个组件&#xff0c;把校验和请求事件放在一个方法里面&#xff0c;用回调或者promise进行异步处理。 发现原因是在校验错误的判断&#xff0c;进行callback之后&#xff0c;页面…...

Game AI ——游戏人工智能(逻辑及剧情生成)

一、Game AI 的介绍 "Game AI"&#xff08;游戏人工智能&#xff09;通常指的是在电子游戏中使用的各种人工智能技术和算法&#xff0c;用于控制游戏中的非玩家角色&#xff08;NPC&#xff09;、敌人、队友等&#xff0c;以及为玩家提供有挑战性的对手或有趣的互动…...

算法基础知识——核函数

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正 核函数&#xff08;Kernel Function&#xff09;是机器学习中一种重要的工具&#xff0c;特别是在支持向量机&#xff08;SVM&#xff09;、核岭回归、核主成分分析&#xff08;KPCA&#xff09;等核…...

安卓xml乱码/加密转换:abx2xml和xml2abx使用及源码介绍

背景&#xff1a; 上一篇文章 android系统中data下的xml乱码无法查看问题剖析及解决方法 发布后&#xff0c;想要寻找一个可以直接把二进制xml和普通xml进行相互转换的&#xff0c;当时还写了相关的方案&#xff0c;但是当时没有找到现成的开源工具&#xff0c;后来经过相关粉…...

slice 截取

JavaScript中的一个数组方法。然而&#xff0c;在Vue 3的应用开发中&#xff0c;slice 方法经常被用于处理数组数据&#xff0c;特别是在需要实现分页、数据截取或数据展示等场景时。 slice 方法的基本用法 slice() 方法返回一个新的数组对象&#xff0c;这一对象是一个由 be…...

XReparentWindow踩坑分析

X11是Linux发行系统中广泛采用的显示协议&#xff0c;各个系统基本上都支持XLib库&#xff0c;作为底层接口&#xff0c;XReparentWindow接口的功能就是重新设置父窗口&#xff0c;注意这个可以跨进程设置父窗口&#xff0c;例如将已经运行的进程的父窗口设置自己的程序Wid&…...

OpenAI动荡,将走向何方、GPT5或许将近、毒舌AI轻松破防网友、最新版 GPT-4o AI 模型得满分 | AGI视界周刊第 4 期

AI 视界周刊由战场小包维护&#xff0c;每周一更新&#xff0c;包含热点聚焦、应用破局、学术前沿、社区热议、智见交锋、跨界 AI、企业动态和争议 AI 八大板块&#xff0c;后续板块划分和内容撰写在周刊迭代过程中持续优化&#xff0c;欢迎大家提出建议。 欢迎大家来到《AI 视…...

RCE---无字母数字webshell

<?php if(isset($_GET[code])){$code $_GET[code];if(strlen($code)>35){die("Long.");}if(preg_match("/[A-Za-z0-9_$]/",$code)){die("NO.");}eval($code); }else{highlight_file(__FILE__); } 分析代码&#xff1a;传参不大于35&…...

有意思的漏洞复现与分析一

目录 一、Linux命令长度限制突破方法 1.在二进制漏洞利用中&#xff0c;某师傅遇到可控数据只有8字节的情况&#xff0c;去掉字符 串尾的\0&#xff0c;限制在7个字符。 一、Linux命令长度限制突破方法 1.在二进制漏洞利用中&#xff0c;某师傅遇到可控数据只有8字节的情况&a…...

力扣题解(按身高排序)

2418. 按身高排序 给你一个字符串数组 names &#xff0c;和一个由 互不相同 的正整数组成的数组 heights 。两个数组的长度均为 n 。 对于每个下标 i&#xff0c;names[i] 和 heights[i] 表示第 i 个人的名字和身高。 请按身高 降序 顺序返回对应的名字数组 names 。 思路&…...

Redis的六种淘汰策略详解

Redis作为一种高性能的键值对存储系统&#xff0c;其数据全部存储在内存中&#xff0c;因此内存管理对Redis的性能至关重要。当Redis的内存使用达到上限时&#xff0c;就需要通过淘汰策略来释放内存空间&#xff0c;以便存储新的数据。Redis提供了六种不同的淘汰策略&#xff0…...

vue3中 ref 和 reactive 的区别

相同&#xff1a;均是声明响应式对象。且声明的响应式对象是深层的 1. 数据类型不同&#xff1a;ref用于包装JavaScript基本类型的数据&#xff08;如字符串、数字、布尔值等&#xff09;&#xff0c;而reactive可以用于包装JavaScript对象和数组等复杂类型的数据。 2.访问方式…...

《单例模式的深度解读:实现方式、破坏情况与利弊权衡》

单例模式 一、单例模式的定义 ​ 单例模式&#xff08;Singleton Pattern&#xff09;是一种常见的软件设计模式&#xff0c;确保一个类只有一个实例存在&#xff0c;并提供一个全局访问点来获取该实例。 二、单例模式的实现方式 ​ 1.懒汉式单例 public class LazySingle…...

010607电压源和电流源受控源

电源的理论部分 1.6电压源和电流源1.理想电压源&#xff1a; 1.6电压源和电流源 1.理想电压源&#xff1a; 其两端电压总能保持定值或一定的时间函数&#xff0c;其值与流过它的电流i无关的元件叫理想电压源。 电路符号&#xff1a;中间与导线直通的圆圈 电压源&#xff1a…...

快乐数求解

编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结果为 1&#xff0c…...