百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

SpringBoot线程池的创建、@Async配置步骤及注意事项

xsobi 2024-11-24 23:35 21 浏览

作者:Muscleheng

blog.csdn.net/Muscleheng/article/details/81409672

前言

最近在做订单模块,用户购买服务类产品之后,需要进行预约,预约成功之后分别给商家和用户发送提醒短信。考虑发短信耗时的情况所以我想用异步的方法去执行,于是就在网上看见了Spring的@Async了。

但是遇到了许多问题,使得@Async无效,也一直没有找到很好的文章去详细的说明@Async的正确及错误的使用方法及需要注意的地方,这里简单整理了一下遇见的问题,Sring是以配置文件的形式来开启@Async,而SpringBoot则是以注解的方式开启。

我们可以使用springBoot默认的线程池,不过一般我们会自定义线程池(因为比较灵活),配置方式有:

  1. 使用 xml 文件配置的方式
  2. 使用Java代码结合@Configuration进行配置(推荐使用)

下面分别实现两种配置方式

第一步、配置@Async

一、springBoot启动类的配置:

在Spring Boot的主程序中配置@EnableAsync,如下所示:

二、Spring XML的配置方式:

1.applicationContext.xml同目录下创建文件threadPool.xml文件:

2.然后在applicationContext.xml中引入threadPool.xml:<import resource="threadPool.xml" />

第二步:创建两个异步方法的类,如下所示:

第一个类(这里模拟取消订单后发短信,有两个发送短信的方法):

第二个类。调用发短信的方法 (异步方法不能与被调用的异步方法在同一个类中,否则无效):

经过测试得到如下结果:

1.没有使用@Async

2.使用了@Async

可以看出,没有使用@Async方式实现的发送短信是同步执行的,意思就是说第一条发送之后再发送第二条,第二条发送成功之后再给用户提示,这样显然会影响用户体验,再看使用了@Async实现的,在执行第一个发送短信方法之后马上开启另一个线程执行第二个方法,显然这样我们的处理速度回快很多。

使用Java代码结合@Configuration注解的配置方式(推荐使用)

1. 新建一个配置类

package com.boot.common.conf;

import java.util.concurrent.ThreadPoolExecutor;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.scheduling.annotation.EnableAsync;

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**

* 线程池配置

*@authorzhh

*

*/

@Configuration

@EnableAsync

public classThreadPoolTaskConfig{

/**

* 默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,

* 当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;

* 当队列满了,就继续创建线程,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝

*/

/** 核心线程数(默认线程数) */

private static final int corePoolSize = 20;

/** 最大线程数 */

private static final int maxPoolSize = 100;

/** 允许线程空闲时间(单位:默认为秒) */

private static final int keepAliveTime = 10;

/** 缓冲队列大小 */

private static final int queueCapacity = 200;

/** 线程池名前缀 */

private static final String threadNamePrefix = "Async-Service-";

@Bean("taskExecutor") // bean的名称,默认为首字母小写的方法名

publicThreadPoolTaskExecutortaskExecutor(){

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

executor.setCorePoolSize(corePoolSize);

executor.setMaxPoolSize(maxPoolSize);

executor.setQueueCapacity(queueCapacity);

executor.setKeepAliveSeconds(keepAliveTime);

executor.setThreadNamePrefix(threadNamePrefix);

// 线程池对拒绝任务的处理策略

// CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

// 初始化

executor.initialize();

return executor;

}

}

2.创建两个异步方法的类(和之前的类类似仅仅是方法上注解不一样),如下所示:

第一个类(这里模拟取消订单后发短信,有两个发送短信的方法):

代码中的 @Async("taskExecutor") 对应我们自定义线程池中的 @Bean("taskExecutor") ,表示使用我们自定义的线程池。

第二个类。调用发短信的方法 (异步方法不能与被调用的异步方法在同一个类中,否则无效):

运行截图:

注意看,截图中的 [nio-8090-exec-1] 是Tomcat的线程名称

[Async-Service-1]、[Async-Service-2]表示线程1和线程2 ,是我们自定义的线程池里面的线程名称,我们在配置类里面定义的线程池前缀:

private static final String threadNamePrefix = "Async-Service-"; // 线程池名前缀,说明我们自定义的线程池被使用了。

注意事项

如下方式会使@Async失效

  • 异步方法使用static修饰
  • 异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类
  • 异步方法不能与被调用的异步方法在同一个类中
  • 类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象
  • 如果使用SpringBoot框架必须在启动类中增加@EnableAsync注解

相关推荐

给织梦栏目增加链接属性rel、nofollow和target

摘要:为了方便管理,直接在织梦后台栏目里自由把控每个栏目对应的链接属性,我们来给织梦栏目增加链接属性rel="nofllow"rel="external"rel=&...

Rust+Tauri2+React+TS剪切板管理桌面端应用开发示例

随着Tauri2.0的发布,Tauri越来越值得关注,当然与名气更大的Electron相比仍有差距,但因其有Rust加持,仍表现出很大潜力,如果想开发【小而美】的桌面端App,Tauri是个不错的选择...

宇宙厂:为什么前端要了解 Interaction to Next Paint (INP)

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!2024年3月,Interactio...

前端知识分享:vue3中,v-model核心用法

本文讲一下:在vue中,用于组件双向绑定的语法,v-model。什么是组件呢?简单来说,就是拼接成网页的一个个元素。我们制作网页就跟搭积木一样,这放一个button,那放一个表单,这放一个div,那...

前端入门——html 表单

前言前面已经学习相关html大部分知识,基本上可以制作出简单的页面,但是这些页面都是静态的,一个网站如果要实现用户的互动交流,这时表单就起到关键的作用,表单的用途很多,它主要用来收集用户的相关信息,是...

web前端Jquery学习笔记一

学习大纲一、了解Jquery1.什么是jqueryJquery是一款优秀的JavaScript框架,它是一个轻量的JS库,它兼容CSS3,还兼容各种浏览器(IE6.0+,火狐1.5+,谷歌,safa...

做个简单的本地弹幕播放器

前言本文仅仅是做一个简单的弹幕播放器本文弹幕播放器仅仅是演示一下发送弹幕功能请跳转本文底部的在线调试代码进行调试最终实现效果如下:Okay.首先你得找到一个弹幕开源库就是这个啦:https://git...

RocketMQ源码分析七之创建ConsumerGroup

在本章中,我们将分析RocketMQ是如何创建订阅组的。看看RocketMQ是如何实现的。如何开启&关闭在部署RocketMQ的Broker的时候,我们通常都会把autoC...

「春运专题」“春运倒计时第二天”(教你如何抢下铺)

工具/原料360极速浏览器方法/步骤在电脑上运行360极速浏览器,如果电脑中没有,不仿装一个试试。进入12306网站主页面。在订票中选中要坐的车次和日期,之后点击“预订”进入登录页面;按提示完成登录操...

初识HTML——列表标签和表单标签

列表标签在html中列表分为无序列表、有序列表和自定义列表(项目列表)。接下来就看看他们有什么不同吧!作用:如果说table标签是用来显示数据的,那么列表标签就是用来进行html页面布局的。无序列表语...

注册windows系统服务

一、把任意exe程序注册成windows系统服务1、方法一:使用windows自带的命令InstallUtil.exe步骤:运行--〉cmd:打开cmd命令框,在命令行里定位到InstallUtil...

DeepSeek火爆全网!我用它做个数学计算题生成器

作为一名家长,你是否曾为孩子的数学作业头疼不已?每天都要手动出题,检查答案,费时费力。最近,我借助DeepSeek的帮助,开发了一个简单实用的“数学计算题生成器”,彻底解决了这个问题!现在,我将分...

“五一”假期火车票抢票攻略:如何在12306网站选择上中下铺

目前,火车票预售期为60天计算,准备“五一”小长假铁路出行的旅客今天可以购票了。记者从北京铁路局获悉,今天(3月3日)起,电话订票与互联网同时发售5月1日之前(含1日)的车票;也就是说3月3日-5日,...

【HarmonyOS Next之旅】兼容JS的类Web开发(四) -> swiper

目录1->创建Swiper组件2->添加属性3->设置样式4->绑定事件5->场景示例编辑1->创建Swiper组件在pages/index...

表单元素之选择类型

表单元素的选择类型可以分为三种:单选多选下拉单选和复选框的属性值可以有两个:disabled(不可操作的)和checked。下拉框的属性值可以是:selected(默认选中)、multiple(...