SpringBoot中的异步多线程使用及避坑指南

SpringBoot中的异步多线程使用及避坑指南
处理请求时需要考虑到系统的性能和响应速度。特别是在处理大量请求或者需要进行耗时操作时,采用异步多线程处理是一种常见的解决方案。Spring Boot提供了@Async注解来支持异步方法调用,结合合适的线程池配置,可以很容易地实现异步多线程处理,提升系统的并发能力和性能。

1.配置线程池

@Configuration
@EnableAsync
public class AsyncConfiguration {
    @Bean("doSomethingExecutor")
    public Executor doSomethingExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数:线程池创建时候初始化的线程数
        executor.setCorePoolSize(10);
        // 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(20);
        // 缓冲队列:用来缓冲执行任务的队列大小
        executor.setQueueCapacity(500);
        // 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("do-something-");
          // 缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
        executor.initialize();
        return executor;
    }
}

在这个配置中,我们使用了ThreadPoolTaskExecutor作为线程池的实现,并且设置了一些关键参数,如核心线程数、最大线程数、缓冲队列大小等。如果不太了解线程池的小伙伴可以看一下之前介绍线程池介绍线程池的核心参数,线程池的执行原理知道

  1. @Async注解
    在需要异步执行的方法上使用@Async注解。这样的方法将会在一个单独的线程中执行,而不会阻塞主线程。
@Slf4j
@Service
public class AsyncService {
   // 指定使用beanname为doSomethingExecutor的线程池
    @Async("doSomethingExecutor")
    public  CompletableFuture<String> doSomething(String message) throws InterruptedException {
        log.info("doSomethingExecutor thread name  ={}", Thread.currentThread().getName());
        Thread.sleep(1000);
        return CompletableFuture.completedFuture(message);
    }
}

doSomething()方法被标记为异步方法,并且指定了使用名为"doSomethingExecutor"的线程池进行执行。

  1. 异步多结果聚合返回CompletableFuture
    在某些情况下,我们可能需要等待多个异步任务执行完毕后再进行下一步操作,这时可以使用CompletableFuture来实现异步多结果的聚合。
@RestController
@RequestMapping
public class AsyncController {

    @Autowired
    private AsyncService asyncService;


    @GetMapping("/open/somethings")
    public List<String> somethings() throws InterruptedException {
        int count = 6;
        List<CompletableFuture<String>> futures = new ArrayList<>();
        List<String> results = new ArrayList<>();
        // 启动多个异步任务,并将 CompletableFuture 对象存储在列表中
        for (int i = 1; i < count; i++) {
            CompletableFuture<String> future = asyncService.doSomething("index: "+i);
            futures.add(future);
        }
        
        for (CompletableFuture<String> future : futures) {
            String result = future.get(); // 阻塞等待异步任务完成并获取结果
            results.add(result);
        }
        return results;
    }
}

我们通过循环启动了多个异步任务,将返回的 CompletableFuture 对象存储在列表中。然后,我们再次循环遍历这些 CompletableFuture 对象,并调用 get() 方法来阻塞等待异步任务完成,获取结果。最后,将结果添加到结果列表中并返回

使用浏览器发送http://localhost:8888/open/somethings,结果如下
在这里插入图片描述
@Async注解会在以下几个场景失效,使用了@Async注解,但就没有走多线程:

异步方法使用static关键词修饰;
异步类不是一个Spring容器的bean(一般使用注解@Component和@Service,并且能被Spring扫描到);
SpringBoot应用中没有添加@EnableAsync注解;
在同一个类中,一个方法调用另外一个有@Async注解的方法,注解不会生效。原因是@Async注解的方法,是在代理类中执行的。
异步方法使用注解@Async的返回值只能为void或者Future及其子类,当返回结果为其他类型时,方法还是会异步执行,但是返回值都是null

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

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

相关文章

在 fstab文件中配置 UUID方式自动挂载数据盘、swap、目录(**)

linux如何挂在硬盘&#xff0c;自动挂载和手动挂载&#xff08;详细说明&#xff09;https://gitcode.csdn.net/65eedcea1a836825ed7a06f4.html 解决linux重启后磁盘挂载失效的问题 https://blog.csdn.net/sugarbliss/article/details/107033034 linux /etc/fstab 文件详细说…

非wpf应用程序项目【类库、用户控件库】中使用HandyControl

文章速览 前言实现方法1、首先需要在NuGet包管理器中添加HandyControl包&#xff1b;2、在Properties目录下添加DesignTimeResources&#xff1b;3、将其中内容替换为官网中于App.xaml添加的内容 参考文章 坚持记录实属不易&#xff0c;希望友善多金的码友能够随手点一个赞。 共…

windows 下用使用api OCI_ConnectionCreate连接oracle报错 TNS:无法解析指定的连接标识符

背景&#xff0c;两台服务器系统一样&#xff0c;oracle版本一样&#xff0c;其中一台服务器在运行程序的时候报错 TNS:无法解析指定的连接标识符 但是PL/SQL可以正常连接&#xff0c;怀疑是oracle配置文件的原因 tnsnames.ora配置文件大概作用&#xff1a;是Oracle客户端的网…

Git的原理和使用(四):理解分布式版本控制系统与远程仓库的相关配置

目录 远程操作 理解分布式版本控制系统 远程仓库 新建远程仓库 克隆远程仓库 向远程仓库推送 拉取远程仓库 配置Git 忽略特殊文件 为命令配置别名 标签管理 理解标签 创建标签 操作标签 远程操作 理解分布式版本控制系统 1、每个人的电脑都是一个完整的版本库&…

文案智能ai改写工具,文案改写很强大

文案智能ai改写工具可以说是文案编辑人员的得力助手&#xff0c;我们都知道文案的最终定稿还要经过后期的修改&#xff0c;基本也没有文案一写就立刻通过的&#xff0c;甚至有的文案是经过文案编人员多次改写通过&#xff0c;所以文案智能ai改写工具在文案修改的过程中起了很大…

机器人是怎么计时的(通用定时器 - 时基单元)

目录 一&#xff0c;引言 二&#xff0c;机器人的“大脑” 三&#xff0c;时基单元介绍 1&#xff0c;定时器框图 2&#xff0c;时基单元 &#xff08;1&#xff09;预分频器 &#xff08;2&#xff09;CNT计数器 &#xff08;3&#xff09;自动重装载寄存器 四&#…

Lilishop商城(windows)本地部署【docker版】

Lilishop商城&#xff08;windows&#xff09;本地部署【docker版】 部署官方文档&#xff1a;LILISHOP-开发者中心 https://gitee.com/beijing_hongye_huicheng/lilishop 本地安装docker https://docs.pickmall.cn/deploy/win/deploy.html 命令端页面 启动后docker界面 注…

【python】flask模板渲染引擎Jinja2中的模板继承,简化前端模块化开发

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

FPGA时钟资源详解(2)——Clock-Capable Inputs

FPGA时钟系列文章总览&#xff1a;FPGA原理与结构&#xff08;14&#xff09;——时钟资源https://ztzhang.blog.csdn.net/article/details/132307564 目录 一、概述 1.1 为什么使用CC 1.2 如何使用CC 二、Clock-Capable Inputs 2.1 SRCC 2.2 MRCC 2.3 其他用途 2.3.1…

Ubuntu 系统下安装 Redis

目录 一、上传 Redis 安装包并解压缩 二、编译 1、安装gcc&#xff0c;不然后面编译报错 2、开始编译 三、生成后台服务 四、修改配置文件 1、设置密码 2、设置后台启动 五、启动服务 一、上传 Redis 安装包并解压缩 tar -zxvf redis-6.0.2.tar.gz 二、编译 1、安装g…

对话 Mines of Dalarnia: Web3 游戏创新,社区驱动与公链共建

作者&#xff1a;stellafootprint.network 嘉宾&#xff1a;Manfred Pack&#xff0c;Mines of Dalarnia 游戏开发总监 采访者&#xff1a;Alex Cooper&#xff0c;Footprint Analytics 北美社区与 BD 负责人 在区块链游戏领域&#xff0c;去中心化和玩家经济正在颠覆传统游戏…

【Java多线程】3——Lock API控制多线程

3 Lock API控制多线程 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记仓库&#x1f449;https://github.com/A-BigTree/tree-learning-notes 个人主页&#x1f449;https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个…

第18次修改了可删除可持久保存的前端html备忘录

第17次修改了可删除可持久保存的前端html备忘录&#xff1a;增加年月日星期&#xff0c;增加倒计时&#xff0c;更改保存区名称可以多个备忘录保存不一样的信息&#xff0c;匹配背景主题&#xff1a;现代深色 <!DOCTYPE html> <html lang"zh"> <head&…

SpringBoot国际化配置流程(超详细)

前言 最新第一次在做SpringBoot的国际化&#xff0c;网上搜了很多相关的资料&#xff0c;都是一些简单的使用例子&#xff0c;达不到在实际项目中使用的要求&#xff0c;因此本次将结合查询的资料以及自己的实践整理出SpringBoot配置国际化的流程。 SpringBoot国际化 "i…

智慧公厕四大核心能力,赋能城市公共厕所智能化升级

公共厕所是城市基础设施中不可或缺的一部分&#xff0c;但由于传统的公共厕所在建设与规划上&#xff0c;存在一定的局限性&#xff0c;导致环境卫生差、管理难度大、使用体验不佳等问题&#xff0c;给市民带来了很多不便。而智慧公厕作为城市智能化建设的重要组成部分&#xf…

谈谈变压器中的位置编码

变压器中的位置编码 一、说明 在上一期的“Transformers for Everyone”系列中&#xff0c;我们介绍了 Transformer 的概念&#xff0c;并深入研究了第一个关键架构元素&#xff1a;输入嵌入。如果你错过了第一集&#xff0c;你可以通过阅读来赶上&#xff1a;适合所有人的变形…

【Linux】 gcc(linux下的编译器)程序的编译和链接详解

目录 前言&#xff1a;快速认识gcc 1. 程序的翻译环境和执行环境 2.编译和链接 2.1翻译环境 2.2编译环境 1. 预处理 gcc -E指令 test.c&#xff08;源文件&#xff09; -o test.i&#xff08;生成在一个文件中&#xff0c;可以自己指定&#xff09; 预处理完成之后就停下来&am…

状态压缩的三种模型

第一种类型&#xff08;摆放方块&#xff09;&#xff1a; 代码如下&#xff1a; #include<iostream> #include<climits> #include<algorithm> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #include<s…

vue3+ts+element home页面侧边栏+头部组件+路由组件组合页面教程

文章目录 效果展示template代码script代码样式代码 效果展示 template代码 <template><el-container class"home"><el-aside class"flex" :style"{ width: asideDisplay ? 70px : 290px }"><div class"aside-left&q…

项目中自动引入神器 - unplugin-auto-import/unplugin-vue-components

前端 项目中 自动引入 神器 前言 在开发中&#xff0c;我们总喜欢站在巨人的肩膀上开发&#xff0c;比如用一些 框架&#xff1a;vue,react, 组件库&#xff1a;element&#xff0c;ant。 工具函数&#xff1a;axios&#xff0c;lodash 现在是模块化时代&#xff0c;我们…