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

优化耗时业务:异步线程在微服务中的应用

大家好,我是程序员大猩猩。

大家都知道,在我们实际开发过程中,我们经常会遇到一些耗时的业务和逻辑,比如说要上传什么大文件,又或者是大文件的数据处理。我们不能一个接口上等着这些耗时任务完成之后了,再返回,那用户体验度会大打折扣的。

这时候,我们最基本的操作就是使用多线程处理或者是异步线程处理。这里我们说一下异步线程处理。

那么我们来说一下,微服务中如何使用异步线程呢?

一、使用 @Async 注解我们来看看它的源码:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Async {/*** A qualifier value for the specified asynchronous operation(s).* <p>May be used to determine the target executor to be used when executing* the asynchronous operation(s), matching the qualifier value (or the bean* name) of a specific {@link java.util.concurrent.Executor Executor} or* {@link org.springframework.core.task.TaskExecutor TaskExecutor}* bean definition.* <p>When specified on a class-level {@code @Async} annotation, indicates that the* given executor should be used for all methods within the class. Method-level use* of {@code Async#value} always overrides any value set at the class level.* @since 3.1.2*/String value() default "";
}

我们看到Async内,只有一个参数value,这个value的设置来确定异步线程指定线程池的名字。

当然这里我们可以不设置这个value,可以使用默认的。但是为什么要设置这个value,来指定线程池呢?因为指定线程是为了控制和管理异步任务。

a. 如果不指定线程池,Spring 默认使用 SimpleAsyncTaskExecutor,这不是一个真正的线程池,因为它为每个任务创建一个新的线程。这可能导致线程数量的快速增长,从而消耗大量系统资源。通过指定一个真正的线程池,如 ThreadPoolTaskExecutor,可以复用线程,减少资源消耗。b. 线程池可以提供更好的性能,因为它可以减少线程创建和销毁的开销。线程池中的线程可以被重复使用,而不是每次执行异步任务时都创建新的线程。

c. 通过为不同的服务或组件指定不同的线程池,可以实现线程隔离。这意味着如果一个服务出现异常或者需要大量时间来处理任务,它不会影响到其他服务的性能。d. 线程池提供了任务调度和管理的能力,比如设置核心线程数、最大线程数、队列容量等,这样可以更精细地控制任务的执行行为。e. 线程池通常提供了任务执行错误的处理机制,比如当任务执行失败时的重试策略。f. 线程池可以提供线程的运行状态和性能指标,这对于监控和调试应用程序是非常有用的。怎么设置线程池?

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;@Configuration
public class ThreadPoolConfig {@Bean(name = "taskExecutor")public ThreadPoolTaskExecutor threadPoolTaskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(2); // 核心线程数executor.setMaxPoolSize(5); // 最大线程数executor.setQueueCapacity(10); // 队列容量executor.setThreadNamePrefix("Async-"); // 线程名称前缀executor.initialize();return executor;}
}

设置好线程池后,我们就可以在方法上使用@Async,开启异步线程了。

@Async("taskExecutor")
public void executeAsyncTask() {// 异步任务逻辑
}

最后要记住:在微服启动类之上,加入注释@EnableAsync就可以了。

@SpringBootApplication
@EnableAsync
public class AsyncApplication {public static void main(String[] args) {SpringApplication.run(AsyncApplication.class, args);}
}

二、使用 CompletableFuture

CompletableFuture 是 Java 8 引入的一个类,用于表示异步计算的结果。通过 CompletableFuture,我们可以很方便地实现异步操作,并且可以链式调用多个异步任务。

@Service
public class CompletableFutureService {public CompletableFuture<String> executeAsyncTask() {return CompletableFuture.supplyAsync(() -> {System.out.println("执行异步任务:" + Thread.currentThread().getName());return "异步任务执行结果";});}
}@RestController
public class CompletableFutureController {@Autowiredprivate CompletableFutureService completableFutureService;@GetMapping("/completableFuture")public CompletableFuture<String> completableFuture() {return completableFutureService.executeAsyncTask();}
}三、组合使用 @Async 和 Future

我们可以通过 @Async 返回一个 Future 对象,以便在需要时获取异步任务的执行结果。

@Service
public class FutureService {@Asyncpublic Future<String> executeAsyncTask() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("执行异步任务:" + Thread.currentThread().getName());return new AsyncResult<>("异步任务执行结果");}
}@RestController
public class FutureController {@Autowiredprivate FutureService futureService;@GetMapping("/future")public String future() throws ExecutionException, InterruptedException {Future<String> future = futureService.executeAsyncTask();return "异步任务执行结果:" + future.get();}
}

本文介绍了在SpringBoot中使用异步线程的三种方式:使用@Async注解、CompletableFuture和@Async结合Future。在实际开发中,我们可以根据具体需求选择合适的异步实现方式,提高应用程序的性能和用户体验。

相关文章:

优化耗时业务:异步线程在微服务中的应用

大家好&#xff0c;我是程序员大猩猩。 大家都知道&#xff0c;在我们实际开发过程中&#xff0c;我们经常会遇到一些耗时的业务和逻辑&#xff0c;比如说要上传什么大文件&#xff0c;又或者是大文件的数据处理。我们不能一个接口上等着这些耗时任务完成之后了&#xff0c;再…...

torch.scatter看图理解

torch.Tensor.scatter 有 4 个参数&#xff1a; scatter(dim, index, src, reduceNone) 先忽略 Reduce&#xff0c;最后再解释。先从最简单的开始。我们有一个 (2,4) 形状的张量&#xff0c;里面填充了 1&#xff1a; 粉红色的符号表示张量结构 并且我们传入相应的参数并得到…...

适合学生党的蓝牙耳机有哪些?盘点四大性价比蓝牙耳机品牌

对于追求高品质音乐体验而又预算有限的学生党来说&#xff0c;一款性价比高的蓝牙耳机无疑是最佳选择&#xff0c;在众多品牌和型号中&#xff0c;如何挑选到既适合自己需求又价格亲民的蓝牙耳机&#xff0c;确实是一个值得思考的问题&#xff0c;作为一个蓝牙耳机大户&#xf…...

【ORB_SLAM系列3】—— 如何在Ubuntu18.04中使用自己的单目摄像头运行ORB_SLAM3(亲测有效,踩坑记录)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、ORB_SLAM3源码编译二、ORB_SLAM3实时单目相机测试1. 查看摄像头的话题2. 运行测试 三. 运行测试可能的报错1. 报错一(1) 问题描述(2) 原因分析(3) 解决 2. …...

Science Advances|柔性超韧半导体纤维的大规模制备(柔性半导体器件/可穿戴电子/纤维器件/柔性电子)

北京大学 雷霆(Ting Lei)团队,在《Science Advances》上发布了一篇题为“Continuous production of ultratough semiconducting polymer fibers with high electronic performance”的论文。论文内容如下: 一、 摘要 共轭聚合物具有良好的光电特性,但其脆性和机械特性差,…...

VirtualBox虚拟机与bhyve虚拟机冲突问题解决@FreeBSD

问题 在安装完bhyve虚拟系统的主机上启动VirtualBox虚拟机的时候&#xff0c;报错&#xff1a;不能为虚拟电脑 debian 打开一个新任务. VirtualBox cant operate in VMX root mode. Please close all other virtualization programs. (VERR_VMX_IN_VMX_ROOT_MODE). 返回 代码…...

【网络层】ICMP 因特网控制协议

文章目录 ICMP 含义以及作用ICMP协议解析结合ICMP协议和ping常见问题 ICMP 含义以及作用 ICMP&#xff1a;Internet control massage protocol 因特网控制协议 Internet控制报文协议ICMP是网络层的一个重要协议。 ICMP协议用来在网络设备间传递各种差错和控制信息&#xff0c;…...

汇编原理(四)[BX]和loop指令

loop&#xff1a;循环 误区&#xff1a;在编译器里写代码和在debug里写代码是不一样的&#xff0c;此时&#xff0c;对于编译器来说&#xff0c;就需要用到[bx] [bx]: [bx]同样表示一个内存单元&#xff0c;他的偏移地址在bx中&#xff0c;比如下面的指令 move bx, 0 move ax,…...

Linux查看设备信息命令

dmidecode | grep Product Name 查看grub版本号&#xff1a;rpm -qa | grep -i "grub" 客户端操作系统版本&#xff1a; cat /etc/issue cat /etc/redhat-release 处理器品牌及型号&#xff1a; less /proc/cpuinfo |grep model...

transformer的特点

Transformers是一种用于处理序列数据的神经网络架构&#xff0c;最初由Vaswani等人在2017年提出&#xff0c;主要用于自然语言处理任务。与传统的循环神经网络&#xff08;RNN&#xff09;和卷积神经网络&#xff08;CNN&#xff09;不同&#xff0c;Transformers采用了一种全新…...

27快28了,想转行JAVA或者大数据,还来得及吗?

转行到JAVA或者大数据领域&#xff0c;27岁快28岁的年龄完全来得及。我这里有一套编程入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习编程&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我在后台发给你。…...

英飞凌 AURIX TriCore 单片机开发入门

文章目录 目的硬件准备AURIX™ Development StudioInfineon MemtoolAURIX™ iLLD Drivers总结 目的 英飞凌的32位 AURIX™ TriCore™ 系列单片机 经常用于汽车和工业领域。开发该系列单片机比较常用的开发环境有 HighTec 和 AURIX™ Development Studio 。本文将基于后者&…...

Centos安装,window、ubuntus双系统基础上安装Centos安装

文章目录 前言一、准备工作二、开始安装1、2、首先选择DATE&TIME2、选择最小安装3、 选择安装位置 总结 前言 因工作需要&#xff0c;我需要在工控机上额外装Centos7系统&#xff0c;不过我是装在机械硬盘上了不知道对性能是否有影响&#xff0c;若有影响&#xff0c;后面…...

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷6(容器云)

#需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包…...

第13章 常用类

一、包装类 二、String String的常用方法&#xff1a; equals&#xff1a;判断内容是否相等&#xff0c;区分大小写。 String str1 "hello";String str2 "Hello";System.out.println(str1.equals(str2));//false equalsIgnoreCase&#xff1a;判断内容…...

15.数组的方法(改变原数组和不改变原数组)

改变原数组 (1)pop 语法:数组名.pop() 作用:删除数组最后一项 返回值:返回被删除的那一项 var arr=["zhangsna","lisi","wanger","mazi"] var res=arr.pop() console.log(arr) //[zhangsna, lisi, wange…...

随后记: uniapp uview u-dropdown 下拉菜单固定高度滑动不生效

使用u-dropdown 下拉组件 按照uview官网讲解使用 配置根本不生效 scroll-y"true" style"height: 200rpx;" 但是在下拉的时候&#xff0c;不能上下滑动 &#xff0c;原因是自带的遮罩层挡住了 解决办法&#xff1a;在下拉菜单打开和关闭的时候&#xff0c…...

一文梭哈动态代理

大家好&#xff0c;这里是教授.F 引入&#xff1a; 先看一个生活化的例子&#xff0c;如果一个明星他会唱歌&#xff0c;会跳舞。但是自己太忙了&#xff0c;没时间去宣传自己和去找工作&#xff0c;所以他需要有人帮他代理。然后呢这个代理者也需要知道他会什么&#xff0c;什…...

如何查询Windows 10电脑的IP地址

如何查询Windows 10电脑的IP地址 引言 在Windows 10操作系统中&#xff0c;查询电脑的IP地址是一项基本而重要的任务&#xff0c;无论是为了配置网络、解决连接问题&#xff0c;还是进行远程访问。 基础知识 IP地址&#xff1a;互联网协议地址&#xff0c;用于标识网络中的…...

java: 警告: 源发行版 8 需要目标发行版 8

前言 该文章中项目背景是&#xff1a;IDEA与设置的版本与实际电脑配置的不一致。也就是说只改了这个团队项目的JDK版本&#xff0c;IDEA上其它项目JDK版本未更改。 提示&#xff1a; IDEA警告&#xff1a;javaX&#xff1a;警告&#xff1a;源发行版 需要目标发行版 简略步…...

CCF-CSP认证 2023年12月 2.因子化简

题解&#xff1a; 通过质数筛法&#xff0c;用个板子函数就行了&#xff0c;计算出质数系数就行了 #pragma GCC optimize(2, 3, "Ofast", "inline") #include <bits/stdc.h> #define endl \n using namespace std; long long int num; const int M…...

基于Vue2与3版本的Element UI与Element Plus入门

基于Vue2与3版本的Element UI与Element Plus入门 Element UI 入门安装引入 Element UI使用组件 Element Plus 入门安装引入 Element Plus使用组件 常用组件自定义主题兼容性和升级社区和支持 Element UI 入门 Element UI 是基于 Vue 2.0 的桌面端组件库&#xff0c;它提供了一…...

Mysql数据库创建自增序列

创建序列表 CREATE TABLE sequence (name varchar(50) NOT NULL,current_value bigint(30) NOT NULL,increment int(11) NOT NULL DEFAULT 1 ) ENGINEInnoDB DEFAULT CHARSETutf8 ROW_FORMATDYNAMIC COMMENT序列表;创建函数 查询当前序列名的序列值 CREATE DEFINERroot% FUNC…...

macOS上用Qt creator编译并跑shotcut

1 简介 Shotcut是一个开源的跨平台的视频编辑软件&#xff0c;支持WIN/MACOS/LINUX等平台&#xff0c;由于该项目的编译较为麻烦&#xff0c;踩坑几许&#xff0c;因此写此文章记录完整编译构建过程&#xff0c;后续按此法编译&#xff0c;可减少走弯路&#xff0c;提高生产力。…...

基于高光谱数据集的创新点实现-高斯核函数卷积神经网络

一、高光谱数据集简介 1.1 数据集简介 数据集链接在这:高光谱数据集(.mat.csv)-科研学术 数据集包含下面三个文件&#xff1a; 文件中包含.mat与.csv,145x145x220, 其实主要使用avirissub.csv文件&#xff0c;在代码上只是将mat文件转成了csv文件。具体avirissub.csv如下&am…...

【python 进阶】 绘图

1. 将多个柱状绘制在一个图中 import seaborn as sns import matplotlib.pyplot as plt import numpy as np import pandas as pd# 创建示例数据 categories [A, B, C, D, E] values1 np.random.randint(1, 10, sizelen(categories)) values2 np.random.randint(1, 10, siz…...

memblock_free_all释放page到buddy,前后nr_free的情况

https://www.cnblogs.com/tolimit/p/5287801.html 在zone_sizes_init 之后&#xff0c;各个node&#xff0c;zone的page总数已知。但是此时的每个order的空闲链表是空的&#xff0c;也就是无法通过alloc_page这种接口来分配。此时page还在memblock管控&#xff0c;需要memblock…...

Django实现websocket

Django实现websocket WebSocket功能使用介绍安装配置WebSocket接口--消息接收者的实现scope通道层 channel layer部署Web客户端连接Mac客户端 WebSocket功能 WebSocket长连接一般用于实现实时功能&#xff0c;例如web端的消息通知、会话等场景。 使用 WebSocket 向 Django 项…...

先进制造aps专题九 中国aps行业分析

国外aps的问题是不给国内客户定制算法 国外aps的算法都很强大&#xff0c;考虑几百个约束条件&#xff0c;各种复杂的工序关系&#xff0c;还有副资源约束特殊规格约束&#xff0c;排程还优化&#xff0c;光c写的算法代码就几十万行甚至上百万行 国内aps的问题是实现不了复杂的…...

力扣hot100:23. 合并 K 个升序链表

23. 合并 K 个升序链表 这题非常容易想到归并排序的思路&#xff0c;俩升序序列合并&#xff0c;可以使用归并的方法。 不过这里显然是一个多路归并排序&#xff1b;包含多个子数组的归并算法&#xff0c;这可以让我们拓展归并算法的思路。 假设n是序列个数&#xff0c;ni是…...