基于Spring 框架中的@Async 注解实现异步任务

@Async 是 Spring 框架中的一个注解,用于实现方法级别的异步执行。使用 @Async 可以让你的代码在非当前线程中执行,从而提高应用的并发性能。

1、 启用异步支持

在 Spring 应用的主配置类或任何其他配置类上添加 @EnableAsync 注解来开启异步任务的支持

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication
@EnableAsync
public class Demo2024Application {public static void main(String[] args) {SpringApplication.run(Demo2024Application.class, args);}
}
2、配置异步执行器

默认情况下,Spring 使用一个内置的 SimpleAsyncTaskExecutor。为了更好地控制线程池,你可以自定义一个 ThreadPoolTaskExecutor 并在配置类中声明它。

   import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.AsyncConfigurer;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;@Configurationpublic class AppConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);  // 核心线程数executor.setMaxPoolSize(10);  // 最大线程数executor.setQueueCapacity(200);  // 队列大小executor.setThreadNamePrefix("MyExecutor-");  // 线程前缀名称executor.initialize();return executor;}}
3、标注异步方法

在需要异步执行的方法上添加 @Async 注解。这个方法将不会阻塞当前调用线程,而是立即返回,异步执行任务。

@Asyncpublic void testAsyncMethod(){log.info("执行Service类的异步方法 start .......");// 执行本Service 类的异步方法 sleep 10s 且每2秒输出一下进度try {for (int i = 0; i < 5; i++) {Thread.sleep(2000);log.info("执行Service类的异步方法 threadName:{}, progress .......:{}",Thread.currentThread().getName(),i);}} catch (InterruptedException e) {throw new RuntimeException(e);}log.info("执行Service类的异步方法 end .......");}
4、注意事项
  • a、异步方法不能直接在控制器(Controller)层使用,因为它们通常需要返回一个响应给客户端,这与异步方法的无返回行为不兼容
  • b、异步方法不能直接调用同一类中的其他异步方法,否则可能会导致死锁。
    通过测试发现,在同一类中调用其它异步方法,打印出来的线程名 都是同一个线程
    测试如下 在同一controller中
  /*** 测试本controller 类的异步方法*/@GetMapping("/testControllerAsync")public void testControllerAsync(){log.info("testControllerAsyncy,调用方法执行打印 开始 .......");log.info("testControllerAsync method threadName:{}",Thread.currentThread().getName());// 调用本controller 类的异步方法testCurrentControllerAsyncMethod();log.info("testControllerAsync,调用方法执行打印 开始 .......");}@Asyncpublic void testCurrentControllerAsyncMethod(){log.info("执行本controller 类的异步方法 start .......");// 执行本controller 类的异步方法 sleep 10s 且每2秒输出一下进度try {for (int i = 0; i < 5; i++) {Thread.sleep(2000);log.info("执行本controller 类的异步方法threadName:{}, progress .......:{}",Thread.currentThread().getName(),i);}} catch (InterruptedException e) {throw new RuntimeException(e);}log.info("执行本controller 类的异步方法 end .......");}

调用接口后 输出内容如下 可以看出 调用方法和被调用的异步方法 打印的threadName 是相同的,且调用方法的结束打印是在异步方法执行结束之后执行的,说明异步方法没生效
在这里插入图片描述
测试在同一service中

@Slf4j
@RestController
public class AsyncTestController {@Resourceprivate AsyncTestService asyncService;/*** 调用Service 类的方法,然后service再调用同service类中的异步方法*/@GetMapping("/testService")public void testService(){log.info("testService controller method 打印开始 .......");log.info("testService controller method threadName:{}",Thread.currentThread().getName());// 调用Service 类的方法,然后service再调用同service类中的异步方法asyncService.testServiceMethod();log.info("testService controller method 打印开始 .......");}
}@Service
@Slf4j
public class AsyncTestService {@Asyncpublic void testAsyncMethod(){log.info("执行Service类的异步方法 start .......");// 执行本Service 类的异步方法 sleep 10s 且每2秒输出一下进度try {for (int i = 0; i < 5; i++) {Thread.sleep(2000);log.info("执行Service类的异步方法 threadName:{}, progress .......:{}",Thread.currentThread().getName(),i);}} catch (InterruptedException e) {throw new RuntimeException(e);}log.info("执行Service类的异步方法 end .......");}public void testServiceMethod(){log.info("testServiceMethod method start .......");log.info("testServiceMethod method threadName:{}",Thread.currentThread().getName());// 调用Service正常方法,然后正常方法调用本service中的异步方法testAsyncMethod();log.info("testServiceMethod method end .......");}
}

调用接口后输出内容如下 可以看出 调用方法及service中的方法和被调用的异步方法 打印的threadName 是相同的,且调用方法的结束打印和service中调用的方法的打印是在异步方法执行结束之后执行的,说明异步方法没生效

在这里插入图片描述

5、 正确的调用 如下,
@Slf4j
@RestController
public class AsyncTestController {@Resourceprivate AsyncTestService asyncService;/*** 测试service 类的中异步方法*/@GetMapping("/testServiceAsync")public void testServiceAsync(){log.info("testServiceAsync controller method start .......");log.info("testServiceAsync controller method threadName:{}",Thread.currentThread().getName());// 调用Service 类的异步方法asyncService.testAsyncMethod();log.info("testServiceAsync controller method end .......");}}@Service
@Slf4j
public class AsyncTestService {@Asyncpublic void testAsyncMethod(){log.info("执行Service类的异步方法 start .......");// 执行本Service 类的异步方法 sleep 10s 且每2秒输出一下进度try {for (int i = 0; i < 5; i++) {Thread.sleep(2000);log.info("执行Service类的异步方法 threadName:{}, progress .......:{}",Thread.currentThread().getName(),i);}} catch (InterruptedException e) {throw new RuntimeException(e);}log.info("执行Service类的异步方法 end .......");}
}

调用后输出如下,可以看出 调用的controller方法 和service中异步方法打印的 线程名称是不相同的,且调用的controller方法的开始打印 及结整打印都是在异步方法打印之前执行的,说明异步方法生效了
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

极验3逆向 JS逆向最新点选验证码 逆向分析详解

目录 声明&#xff01; 一、请求流程分析 二、w参数生成位置 三、主要问题 四、结果展示 原创文章&#xff0c;请勿转载&#xff01; 本文内容仅限于安全研究&#xff0c;不公开具体源码。维护网络安全&#xff0c;人人有责。 声明&#xff01; 本文章中所有内容仅供学习交流…

Pytorch 1.9.0环境安装

pytorch官方链接: https://pytorch.org/get-started/previous-versions/ 安装指令&#xff1a;conda install pytorch1.9.0 torchvision0.10.0 torchaudio0.9.0 cudatoolkit11.3 -c pytorch -c conda-forge 报错&#xff1a;Solving environment: unsuccessful initial attemp…

分支机构多,如何确保文件跨域传输安全可控?

随着企业全球化发展&#xff0c;分支机构的分布越来越广泛&#xff0c;跨域文件传输需求也随之增加。然而&#xff0c;跨域文件传输面临的数据安全和传输效率问题&#xff0c;使得构建一个安全、可控的文件交换系统成为迫切需求。FileLink跨网文件交换系统通过综合的技术手段和…

Java常见集合类一(List)

一、Collection接口及其常见实现子类、子接口 由上图可以看出&#xff0c;Collection 接口实现了 Iterable 接口&#xff1b; Iterable接口是Java集合类中的核心接口之一&#xff0c;实现该接口的类具有迭代功能&#xff0c;它提供了能够对实现它的子类 中的元素进行逐个遍历的…

Android 13 sysprop_library新增属性

前提 我们在androidP及之前的版本&#xff0c;平台侧及应用层开发习惯于通过调用&#xff08;或者反射&#xff09;SystemProperties系统API的方式进行系统属性的读写。Android R以后&#xff0c;平台侧代码采用了一种将系统属性封装成类方法的形式供开发者调用。 Android R以…

go语言,golang,linux,unbantu安装

查看系统是arm还是amd uname -m 命令可以显示系统的架构类型&#xff1a; uname -m输出可能是&#xff1a; x86_64&#xff1a;表示是 AMD64 架构&#xff08;即 64 位的 x86 架构&#xff09;。aarch64&#xff1a;表示是 ARM64 架构&#xff08;即 64 位的 ARM架构&#xf…

SMB工具横向移动

一. SMB工具介绍和使用 1.介绍 2013年的Defcon上&#xff0c;就引入了smbexec&#xff0c;后续 smbexec 被 Impacket 进一步完善了。在Impacket中支持明文认证&#xff0c;NTLM认证&#xff0c;Aeskey认证等方式&#xff01; 2. 使用方法 命令&#xff1a; smbexec.exe 用户…

【计算机毕业设计】基于SSM+Vue的线上旅行信息管理系统【源码+lw+部署文档】

目录 摘 要 第1章 绪论 1.1背景及意义 1.2 国内外研究概况 1.3 研究的内容 第2章 相关技术 2.1 Java简介 2.2 SSM三大框架 2.3 MyEclipse开发环境 2.4 Tomcat服务器 2.5 MySQL数据库 第3章 系统分析 3.1 需求分析 3.2 系统可行性分析 3.2.1技术可行性&#xff1a;技术背景 …

Debug-011-ES6中的链判断运算符(?.)

这个问题的来源是&#xff1a; 前端在请求后端接口&#xff0c;拿到的数据&#xff0c;有可能是这样的&#xff1a; data:{a:{b:{c:{d:""}}} } 我们前端小伙伴联调时需要取到d的值&#xff0c;我以前是这样写的&#xff1a; // 错误的写法 const value data.a.b.c…

ACM Proceedings Template 使用方法

模板导入 打开ACM Primary Article Template官网&#xff0c;可以看到自带overleaf模板&#xff0c;接下来我们使用overleaf来自动导入模板。 选择你需要的ACM Conference or Journals模板&#xff0c;然后Open as Template 栏目说明 接下来依次解释一下左边栏目的作用 …

5月28号总结

刷题记录 1.A. Phone Desktop 输入&#xff1a; 11 1 1 7 2 12 4 0 3 1 0 8 1 0 0 2 0 15 0 8 2 0 9 输出&#xff1a; 1 1 2 2 1 1 0 1 1 2 5 题意&#xff1a;题目给我们1x1和2x2的图标个数&#xff0c;让我们求最少需要多少个5x3的屏幕。 思路&#xff1a;当只看2x2的图…

开源与闭源:AI大模型发展路径的博弈

一、引言 在人工智能&#xff08;AI&#xff09;领域&#xff0c;大模型以其卓越的性能和广泛的应用前景&#xff0c;成为了近年来技术发展的热点。然而&#xff0c;在大模型的发展路径上&#xff0c;开源与闭源两种模式一直存在着激烈的博弈。本文将深入探讨这两种模式在大模…

module ‘plotting‘ has no attribute ‘EpisodeStats‘

plotting.py 的版本不同&#xff0c;可以使用下列版本 reinforcement-learning/lib/plotting.py at master dennybritz/reinforcement-learning GitHubImplementation of Reinforcement Learning Algorithms. Python, OpenAI Gym, Tensorflow. Exercises and Solutions to a…

如何将云服务器上操作系统由centos切换为ubuntu

本文将介绍如何将我们购买的云服务器上之前装的centos切换为ubuntu&#xff0c;云服务器以华为云为例&#xff0c;要切换的ubuntu版本为ubuntu20.04。 参考官方文档&#xff1a;切换操作系统_弹性云服务器 ECS (huaweicloud.com) 首先打开华为云官网&#xff0c;登录后点击右…

MongoDB分片集群容灾方案

MongoDB分片集群容灾方案 1. 集群同步工具介绍1.1 第三方数据同步工具mongoshake1.2 官方同步工具mongosync 2. 工具对比2.1 数据一致性2.2 稳定性和可靠性2.3 维护成本 3. 总结 1. 集群同步工具介绍 最近客户咨询MongoDB分片集群市面上主流的容灾方案&#xff0c;所以抽空整理…

安卓六种页面加载优化方案对比总结

根据工作经验&#xff0c;笔者提炼了六种页面加载优化方式&#xff0c;按照业务与非业务&#xff0c;将六种加载方式分为两类&#xff1a; 业务类 控制业务与UI的执行顺序、控制多业务之间的执行顺序 ①预加载&#xff1a;是指在进入页面之前&#xff0c;提前获得页面所需得数据…

直播预告|中服云第5代`工业物联产品线上发布会

我国作为全球制造业的领军者&#xff0c;拥有世界上最完整且健全的制造业产业链。但随着各企业规模的扩大和设备的增加&#xff0c;企业设备管理面临的难点和挑战也越来越多。 为了满足企业不断提高的设备管理需求&#xff0c;中服云即将推出全新的“设备全生命周期管理系统5.…

机器学习之聚类学习

聚类算法 概念 根据样本之间相似性&#xff0c;将样本划分到不同类别种&#xff0c;不同相似度计算方法&#xff0c;会得到不同聚类结果&#xff0c;常用相似度计算方法为&#xff1a;欧氏距离 目的是在没有先验知识情况下&#xff0c;自动发现数据集种内在结构和模式 无监督…

告别裸奔,聊聊主流消息队列的认证和鉴权!

大家好&#xff0c;我是君哥。 我们在使用消息队列时&#xff0c;经常关注的是消息队列收发消息的功能。但好多时候需要对客户端有一定的限制&#xff0c;比如只有持有令牌的客户端才能访问集权&#xff0c;不允许 Producer 发送消息到某一个 Topic&#xff0c;或者某一个 Top…

人脸识别——Webface-OCC遮挡人脸识别算法解析

1. 概述 自2019年被誉为人脸识别技术的元年&#xff0c;各地纷纷引入这项技术。然而&#xff0c;自2020年起&#xff0c;为了抵御冠状病毒&#xff08;COVID-19&#xff09;的全球传播&#xff0c;人们普遍开始佩戴口罩。众所周知&#xff0c;现有人脸识别模型在面对遮挡物&am…