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

Java 异步编程实战:Thread、线程池、CompletableFuture、@Async 用法与场景

       在平常的软件开发工作中,我们总会遇到一些特殊的功能场景,比如系统操作日志的异步记录、海量数据的文件导出、多维度报表的生成任务等。这些功能往往具有一个共同的特点:执行过程耗时较长,如果采用传统的同步处理方式,会导致用户界面卡顿、接口响应超时,甚至占用核心业务线程资源,影响整个系统的运行效率与稳定性。这个时候就需要引入异步了,那么常见的实现异步的方式有哪些呢?今天来简单总结下。

       一:@Async 注解

        1:使用场景:

        (1):记录系统日志
(2):非实时通知推送
(3):缓存异步刷新

        2:示例:

@Async
public void logActionAsync(String userId, String context) {try {// 模拟日志写入耗时(如写数据库、文件)Thread.sleep(1000);System.out.println("【异步线程】日志记录完成");} catch (InterruptedException e) {e.printStackTrace();}
}@SpringBootApplication(scanBasePackages = {"cn.xxx.xxxx"})
@EnableAsync
public class StarterApplication {public static void main(String[] args) {SpringApplication.run(StarterApplication.class, args);}
}

        二:线程池

        1:使用场景:

        (1):接口高并发异步处理
(2):定时任务集中调度
(3):计算密集型任务处理

        2:示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;@Configuration
public class TaskThreadPoolConfig {// 核心线程数,一般根据业务并发量等合理设置,这里假设设为5private static final int CORE_POOL_SIZE = 5;// 最大线程数,当任务过多时可临时扩充的线程数量,设为10private static final int MAXIMUM_POOL_SIZE = 10;// 线程空闲时间,单位为秒,空闲超过这个时间的线程会被回收,设为60秒private static final int KEEP_ALIVE_TIME_SECONDS = 60;// 阻塞队列,用于存放等待执行的任务,这里使用LinkedBlockingQueue,容量设为100private static final BlockingQueue<Runnable> WORK_QUEUE = new LinkedBlockingQueue<>(100);@Bean("taskThreadPoolExecutor")public ThreadPoolExecutor taskThreadPoolExecutor() {return new ThreadPoolExecutor(CORE_POOL_SIZE,MAXIMUM_POOL_SIZE,KEEP_ALIVE_TIME_SECONDS,TimeUnit.SECONDS,WORK_QUEUE,// 线程工厂,可自定义线程的创建方式、名称等,这里使用默认的ThreadPoolExecutor.defaultThreadFactory(),// 拒绝策略,当线程池和队列都满了后如何处理新任务,这里采用调用者运行策略new ThreadPoolExecutor.CallerRunsPolicy());}
}

        调用:

@Service
public class AsyncLogService {@Autowiredprivate LogService logService;@Autowiredprivate ThreadPoolExecutor taskThreadPoolExecutor;// 提交异步任务public void submitLogTask(String userId, String context) {taskThreadPoolExecutor.execute(() -> logService.logActionAsync(userId, context));}}

       三:Thread + Callable

        1:使用场景:

        (1):独立数据查询与计算
(2):第三方接口异步调用

        2:示例:

@Service
public class AsyncLogService {@Autowiredprivate LogService logService;public void saveInfo() {// 无返回值(Runnable)new Thread(() -> {try {logService.logActionAsync("1", "新增");System.out.println("Thread 异步任务执行完成");} catch (Exception e) {e.printStackTrace();}}).start();}public String saveInfoResult() throws ExecutionException, InterruptedException {Callable<String> task = () -> {logService.logActionAsync("1", "新增");return "success";};FutureTask<String> futureTask = new FutureTask<>(task);new Thread(futureTask).start();String result = futureTask.get();return result;}}

       四:CompletableFuture

        1:使用场景

        (1):多任务串行依赖
(2):任务组合与结果转换
(3):多任务并行执行

        2:示例:

@Service
public class AsyncLogService {@Autowiredprivate LogService logService;public void saveInfo() throws ExecutionException, InterruptedException {// 1. 无返回值的异步任务(runAsync)CompletableFuture<Void> noResultFuture = CompletableFuture.runAsync(() -> {// 业务逻辑处理logService.logActionAsync("11", "新增");System.out.println("无返回值任务执行结束");});// 2. 有返回值的异步任务(supplyAsync)CompletableFuture<String> resultFuture = CompletableFuture.supplyAsync(() -> {// 业务逻辑处理String result = logService.logActionAsync("11", "新增");System.out.println("有返回值任务执行结束");return result;});// 等待无返回值任务完成noResultFuture.get();// 等待有返回值任务完成并获取结果String result = resultFuture.get();}}

       五:总结

        以上为常见的几种实现异步的方式。简单日志记录可用@Async,计算密集型任务适合定制线程池,复杂业务流程推荐CompletableFuture。掌握多种异步实现方式,能够让我们在系统性能和代码可维护性之间找到最佳平衡点。


文章转载自:

http://vdUZ2Dxj.wsxxq.cn
http://tRv5f5zw.wsxxq.cn
http://EgyT6IrD.wsxxq.cn
http://l7gcVqk0.wsxxq.cn
http://j9IycMMl.wsxxq.cn
http://Lrimuq4X.wsxxq.cn
http://oEh9X8ZY.wsxxq.cn
http://uGsxFWd3.wsxxq.cn
http://I3OhLyBM.wsxxq.cn
http://utngEvmR.wsxxq.cn
http://7HeNequ6.wsxxq.cn
http://entxLbqX.wsxxq.cn
http://S41pwDuD.wsxxq.cn
http://hHHdMEvg.wsxxq.cn
http://bHnlxbBa.wsxxq.cn
http://J9AvRmLN.wsxxq.cn
http://mwGJDLJG.wsxxq.cn
http://BVXvNSXz.wsxxq.cn
http://WB1MB6h8.wsxxq.cn
http://x7nvyijU.wsxxq.cn
http://W1KOZUQF.wsxxq.cn
http://bloOti3x.wsxxq.cn
http://95OLdsbc.wsxxq.cn
http://f5LGCp9y.wsxxq.cn
http://JyTrhkys.wsxxq.cn
http://zJOxrIFU.wsxxq.cn
http://LCPy6AF5.wsxxq.cn
http://KjDYSiNA.wsxxq.cn
http://RXAiOXPy.wsxxq.cn
http://Mr6Xeg2m.wsxxq.cn
http://www.dtcms.com/a/388439.html

相关文章:

  • 贪心算法应用:硬币找零问题详解
  • while语句中的break和continue
  • 10cm钢板矫平机:一场“掰直”钢铁的微观战争
  • Python实现计算点云投影面积
  • C++底层刨析章节二:迭代器原理与实现:STL的万能胶水
  • 学习Python中Selenium模块的基本用法(14:页面打印)
  • 便携式管道推杆器:通信与电力基础设施升级中的“隐形推手”
  • leetcode 349 两个数组的交集
  • UV映射!加入纹理!
  • 车辆DoIP声明报文/识别响应报文的UDP端口规范
  • Elasticsearch 2.x版本升级指南
  • OpenCV 人脸检测、微笑检测 原理及案例解析
  • [Python编程] Python3 集合
  • [性能分析与优化]伪共享问题(perf + cpp)
  • OC-动画实现折叠cell
  • 关于层级问题
  • Linux基础命令汇总
  • getchar 和 putchar
  • 【序列晋升】35 Spring Data Envers 轻量级集成数据审计
  • 快速入门HarmonyOS应用开发(二)
  • 绿联、极空间、飞牛NAS无需安装,实现快速远程访问
  • Datawhale 理工科-大模型入门实训课程 202509 第1次作业
  • 城市治理综合管理平台
  • 《嵌入式硬件(十三):基于IMX6ULL的增强型中断周期定时器(EPIT)操作》
  • PM2 入门指南与常用命令(含 开机自启、Node.js 及 Java 服务部署)
  • 汽车多核架构中内存系统故障检测的改进算法
  • C++真的比Python更快吗?
  • 【实操分享】使用 SeeDream 4.0 进行 AI 修图——开启专属“AI 云旅拍”
  • 不依赖第三方,不销毁重建,loveqq 框架如何原生实现动态线程池?
  • Python中正则的三个基础方法