SpringBoot异步任务

一、注解实现

@EnableAsync注解

创建一个配置类,并在类上添加@EnableAsync注解,用来启用异步支持。

@Configuration
@EnableAsync
public class AsyncConfig {
}

或者,在启动类上添加@EnableAsync注解,用来启用异步支持。

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

异步任务类

创建一个包含异步方法的类,并在方法上添加@Async注解。

@Service
public class MyAsyncService {// 默认线程池@Asyncpublic void asyncTask() {try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}// 异步执行的任务逻辑System.out.println("异步任务正在执行");}public void task() {// 同步执行的任务逻辑System.out.println("其他任务正在执行");}
}

调用异步方法

asyncTask方法将在一个单独的线程中异步执行,而主线程将继续执行其他任务。

确保项目中添加了spring-boot-starter-async依赖,这样异步任务的支持才能生效。

注意:异步方法 和 调用方法 不能在同一个类中。

@RestController
@RequestMapping("/api")
public class MyController {@Autowiredprivate MyAsyncService myAsyncService;@GetMapping("/asyncTask")public String asyncTask() {long start = System.currentTimeMillis();// 调用异步方法myAsyncService.asyncTask();// 主线程的其他逻辑myAsyncService.task();System.out.println("方法结束,执行耗时:" + (System.currentTimeMillis() - start));return "OK";}
}

对比

使用@Async注解,主线程马上返回,异步任务继续执行。
在这里插入图片描述

输出:
其他任务正在执行
方法结束,执行耗时:0
异步任务正在执行

不使用@Async注解,主线程方法全部同步执行。
在这里插入图片描述

输出:
异步任务正在执行
其他任务正在执行
方法结束,执行耗时:5015

使用自定义线程池

配置类中创建自定义线程池。

@Configuration
@EnableAsync
public class AsyncConfig {@Bean(name = "customTaskExecutor")public TaskExecutor customTaskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setThreadNamePrefix("CustomThread-");// CPU密集型:corePoolSize = CPU核数 + 1;IO密集型:corePoolSize = CPU核数 * 2int corePoolSize = Runtime.getRuntime().availableProcessors() + 1;executor.setCorePoolSize(corePoolSize); // 核心线程数目executor.setMaxPoolSize(corePoolSize); // 最大线程数executor.setKeepAliveSeconds(30); // 线程空闲后的最大存活时间executor.setQueueCapacity(100); // 阻塞队列大小,当核心线程使用满时,新的线程会放进队列// 线程执行的拒绝策略executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.initialize();return executor;}
}

在异步服务类上,使用@Async注解并指定value属性为自定义线程池的名字。

@Service
public class MyAsyncService {// 不指定则使用默认线程池@Async("customTaskExecutor")public void asyncTask() {try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}// 异步执行的任务逻辑System.out.println("异步任务正在执行");}
}

asyncTask方法将在名为customTaskExecutor的自定义线程池中执行。

确保异步任务调用方仍然使用@Autowired注解注入MyAsyncService,Spring Boot会自动关联使用相应的自定义线程池执行异步任务。

二、CompletableFuture实现

异步任务类

CompletableFuture是Java 8引入的一种异步编程的方式,它提供了更为灵活和强大的异步操作支持。

@Service
public class MyAsyncService {// 线程池,也可以使用自定义的线程池private final Executor customExecutor = Executors.newFixedThreadPool(5);public CompletableFuture<Void> performAsyncTask() {return CompletableFuture.runAsync(() -> {try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}// 异步执行的任务逻辑System.out.println("异步任务正在执行");}, customExecutor);}
}

在这个例子中,performAsyncTask方法返回了一个CompletableFuture<Void>,这表示异步任务没有返回值。CompletableFuture.runAsync(...)方法接受一个Runnable作为参数,并使用customExecutor作为执行器执行异步任务。

调用异步方法

@RestController
@RequestMapping("/api")
public class MyController {@Autowiredprivate MyAsyncService myAsyncService;@GetMapping("/triggerAsyncTask")public String triggerAsyncTask() throws ExecutionException, InterruptedException {// 调用异步方法myAsyncService.performAsyncTask().get();// 主线程的其他逻辑return "OK";}
}

在Controller中,可以通过CompletableFuture.get()方法来等待异步任务的完成。

需要注意的是,get()方法会阻塞,等待到异步方法执行完成,且get()方法可能会抛出InterruptedExceptionExecutionException异常,因此需要进行适当的异常处理。

使用CompletableFuture的好处在于,你可以在异步任务中进行更复杂的操作,例如处理异步任务的结果、合并多个异步任务等。

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

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

相关文章

【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案

【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案 大家好 我是寸铁&#x1f44a; 总结了一篇Error: only one service expected goctl一键转换生成rpc服务错误解决方案的文章✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 问题背景 今天寸铁在…

最新GPT4.0使用教程,AI绘画,GPT语音对话使用,DALL-E3文生图

一、前言 ChatGPT3.5、GPT4.0、GPT语音对话、Midjourney绘画&#xff0c;文档对话总结DALL-E3文生图&#xff0c;相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚至也可以和…

大模型日报-20240204

文章目录 大模型也有小偷&#xff1f;为保护你的参数&#xff0c;上交大给大模型制作「人类可读指纹」阿里全新Agent玩转手机&#xff1a;刷短视频自主点赞评论&#xff0c;还学会了跨应用操作代谢数据集上四项指标达94%~98%&#xff0c;西南交大团队开发多尺度图神经网络框架&…

2024杭州国际安防展览会:引领数字城市安全与智能未来

随着科技的不断进步&#xff0c;数字城市已经成为未来城市发展的重要趋势。作为数字城市建设的重要组成部分&#xff0c;安防技术的创新与应用对于保障城市安全、提高生活品质具有重要意义。为此&#xff0c;2024杭州国际安防展览会将于4月份在杭州国际博览中心隆重召开&#x…

物联网与智慧景区的未来:机遇与挑战并存

随着科技的不断发展&#xff0c;物联网技术在智慧景区中的应用越来越广泛&#xff0c;为旅游业带来了巨大的变革。然而&#xff0c;在物联网与智慧景区的未来发展中&#xff0c;机遇与挑战并存。本文将探讨物联网与智慧景区面临的机遇和挑战&#xff0c;并提出应对措施&#xf…

最简单的基于 FFmpeg 的 AVfilter 例子(水印叠加)

最简单的基于 FFmpeg 的 AVfilter 例子&#xff08;水印叠加&#xff09; 最简单的基于 SDL2 的音频播放器正文工程文件下载 参考雷霄骅博士的文章&#xff0c;链接&#xff1a;最简单的基于FFmpeg的AVfilter例子&#xff08;水印叠加&#xff09; 最简单的基于 SDL2 的音频播…

BridgeTower:融合视觉和文本信息的多层语义信息,主打复杂视觉-语言任务

BridgeTower 核心思想子问题1&#xff1a;双塔架构的局限性子问题2&#xff1a;不同层次的语义信息未被充分利用子问题3&#xff1a;模型扩展性和泛化能力 核心思想 论文&#xff1a;https://arxiv.org/pdf/2206.08657.pdf 代码&#xff1a;https://github.com/microsoft/Bri…

背景样式de七七八八

一&#xff0c;简介 背景属性可以设置背景颜色、背景图片、背景平铺、背景图片位置、背景图像固定等。 1.1背景颜色&#xff08;background-color&#xff09; background-color&#xff1a;transparent/color&#xff1b; 默认值为transparent&#xff08;透明的&#xff…

LeetCode18. 四数之和

18. 四数之和 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#xff…

SpringCloud-微服务概述、SpringCloud入门概述、服务提供与消费

1.学习前言 1.1 学习前提 熟练使用SpringBoot 微服务快速开发框架了解过Dubbo Zookeeper 分布式基础电脑配置内存不低于8G 1.2 文章大纲 Spring Cloud 五大组件 服务注册与发现——Netflix Eureka负载均衡&#xff1a; ​ 客户端负载均衡——Netflix Ribbon ​ 服务端负载…

5.0 HDFS 集群服务建立教程

HDFS 集群是建立在 Hadoop 集群之上的&#xff0c;由于 HDFS 是 Hadoop 最主要的守护进程&#xff0c;所以 HDFS 集群的配置过程是 Hadoop 集群配置过程的代表。 使用 Docker 可以更加方便地、高效地构建出一个集群环境。 每台计算机中的配置 Hadoop 如何配置集群、不同的计…

vscode 括号 python函数括号补全

解决方法 在setting.json中添加 “python.analysis.completeFunctionParens”: true 打开设置&#xff1b; 点击图中按钮打开setting.json文件 添加 “python.analysis.completeFunctionParens”: true