springBoot服务整合线程池ThreadPoolTaskExecutor与@Async详解使用
ThreadPoolExecutor:=======这个是java自己实现的线程池执行类,基本上创建线程池都是通过这个类进行的创建。
ThreadPoolTaskExecutor:========这个是springboot基于ThreadPoolExecutor实现的一个线程池执行类,包装类。
1、Spring默认的@Async用线程池名字为SimpleAsyncTaskExecutor。
2、Spring异步线程池的接口类是TaskExecutor,本质还是java.util.concurrent.Executor,没有配置的情况下,默认使用的是simpleAsyncTaskExecutor。
3、标注@Async注解的方法和调用的方法一定不能在同一个类下,这样的话注解会失效,具体原因不多说
注意:
在springboot当中,如果没有配置线程池的话,springboot会自动配置一个ThreadPoolTaskExecutor线程池到bean当中,我们调用只需要
@Autowired
ThreadPoolTaskExecutor threadPoolTaskExecutor;
第一步: 首先在application启动类添加@EnableAsync
@SpringBootApplication @EnableAsync //首先在application启动类添加@EnableAsync public class ThreadpoolApplication { public static void main(String[] args) { SpringApplication.run(ThreadpoolApplication.class, args); } }
第二步:配置线程池,不配置的话使用springboot默认的线程池。
package com.aswatson.csc.task.conf; import java.util.concurrent.Executor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @Configuration @EnableAsync public class AsyncThreadConfiguration { @Bean("kafkaThreadExecutor") public Executor asyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10);//核心线程数 executor.setMaxPoolSize(20);//最大线程数 executor.setKeepAliveSeconds(60);//空闲线程存活时间 executor.setThreadNamePrefix("kafkaThreadAsync-"); executor.initialize(); return executor; } }
第三步:测试1:在需要异步执行的方法上加上@Async注解。
@Service public class AsyncTest { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Async public void hello(String name){ customerEventLogMapper.insert(customerEventLog); logger.info("异步线程启动 started."+name); } }
第四步:测试2:使用注入的模式:
package com.example.apidemo.completableFutrue; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import java.time.LocalDateTime; @Service public class AsyncService { @Autowired ThreadPoolTaskExecutor threadPoolTaskExecutor; public void addEventLog(String buId, String status){ CustomerEventLogPO customerEventLog = new CustomerEventLogPO(); customerEventLog.setUuid(uuid); customerEventLog.setStatus(status); customerEventLog.setCreated(LocalDateTime.now()); customerEventLogMapper.insert(customerEventLog); threadPoolTaskExecutor.submit(new Thread(()->{ customerEventLogMapper.insert(customerEventLog); })); //submit有返回值 threadPoolTaskExecutor.execute(new Thread(()->{ customerEventLogMapper.insert(customerEventLog); })); //execute无返回值 } }
注意: 如果配置多个线程池,该如何指定线程池呢?
方式1: @Resources("kafkaThreadExecutor")。
方式2: 如果有多个线程池,但是在@Async注解里面没有指定的话,会默认加载第一个配置的线程池。
======================================================================================================================================================================
另外需要注意的是:关于注解失效需要注意以下几点:
- 注解的方法必须是public方法
- 方法一定要从另一个类中调用,也就是从类的外部调用,类的内部调用是无效的,因为@Transactional和@Async注解的实现都是基于Spring的AOP,而AOP的实现是基于动态代理模式实现的。那么注解失效的原因就很明显了,有可能因为调用方法的是对象本身而不是代理对象,因为没有经过Spring容器。
- 异步方法使用注解@Async的返回值只能为void或者Future
==================================================================================================================================================================================================
// @Bean()的拒绝策略:
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
拒绝策略:如果(总任务数 - 核心线程数 - 任务队列数)-(最大线程数 - 核心线程数)> 0 的话,则会出现线程拒绝。举例:( 12 - 5 - 2 ) - ( 8 - 5 ) > 0,会出现线程拒绝。线程拒绝又分为 4 种策略,分别为:
-
- CallerRunsPolicy():交由调用方线程运行,比如 main 线程。
- AbortPolicy():直接抛出异常。
- DiscardPolicy():直接丢弃。
- DiscardOldestPolicy():丢弃队列中最老的任务。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南