Spring + asyncTool:实现复杂任务的编排

一、集成到 Spring Boot

1. 添加依赖

在项目的pom.xml文件中添加asyncTool的依赖:

<dependency> <groupId>com.jd.platform</groupId> <artifactId>asyncTool</artifactId> <version>版本号</version> </dependency>

2. 配置线程池

虽然asyncTool内部会管理线程池,但为了更好地控制线程的使用,可以自定义线程池。以下是两种配置方式:

1)自定义线程池
@Configuration @EnableAsync // 开启线程池 public class TaskExecutePool { @Autowired private TaskThreadPoolConfig config; @Bean public Executor myTaskAsyncPool() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(config.getCorePoolSize()); // 核心线程池大小 executor.setMaxPoolSize(config.getMaxPoolSize()); // 最大线程数 executor.setQueueCapacity(config.getQueueCapacity()); // 队列容量 executor.setKeepAliveSeconds(config.getKeepAliveSeconds()); // 活跃时间 executor.setThreadNamePrefix("MyExecutor-"); // 线程名字前缀 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略 executor.initialize(); return executor; } }
2)修改原生 Spring 异步线程池的装配
@Configuration @EnableAsync // 开启线程池 public class NativeAsyncTaskExecutePool implements AsyncConfigurer { @Autowired private TaskThreadPoolConfig config; @Bean public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(config.getCorePoolSize()); executor.setMaxPoolSize(config.getMaxPoolSize()); executor.setQueueCapacity(config.getQueueCapacity()); executor.setKeepAliveSeconds(config.getKeepAliveSeconds()); executor.setThreadNamePrefix("MyExecutor2-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return (ex, method, objects) -> { log.error("==========================" + ex.getMessage() + "=======================", ex); log.error("exception method:" + method.getName()); }; } }

二、核心方法说明

1. IWorker 接口

  • action(T object, Map<String, WorkerWrapper> allWrappers):任务的具体执行逻辑。object 是任务的输入参数,allWrappers 是所有任务的包装类集合,可用于获取其他任务的结果。

  • defaultValue():任务超时或异常时的默认返回值。

2. ICallback 接口

  • begin():任务开始时的回调。

  • result(boolean success, T param, WorkResult<V> workResult):任务执行结果的回调。success 表示任务是否成功,param 是任务的输入参数,workResult 是任务的执行结果。

3. WorkerWrapper 类

  • id:任务的唯一标识。

  • param:任务的输入参数。

  • worker:任务的具体实现。

  • callback:任务的回调实现。

  • depend:任务的依赖关系,定义任务的执行顺序。

  • next:任务的后续任务,用于定义任务的执行顺序。

三、详细使用方式及示例

1. 串行任务

任务按顺序依次执行。以下是一个串行任务的示例:

// 定义任务 A WorkerWrapper wrapperA = new WorkerWrapper.Builder<Integer, Integer>() .id("workerA") .worker(new WorkerA()) .callback(new WorkerA()) .param(1) .build(); // 定义任务 B,依赖于任务 A WorkerWrapper wrapperB = new WorkerWrapper.Builder<Integer, Integer>() .id("workerB") .worker(new WorkerB()) .callback(new WorkerB()) .param(2) .depend(wrapperA) .build(); // 定义任务 C,依赖于任务 B WorkerWrapper wrapperC = new WorkerWrapper.Builder<Integer, Integer>() .id("workerC") .worker(new WorkerC()) .callback(new WorkerC()) .param(3) .depend(wrapperB) .build(); // 提交任务 Async.beginWork(1000, wrapperA);

2. 并行任务

多个任务同时执行。以下是一个并行任务的示例:

// 定义任务 A WorkerWrapper wrapperA = new WorkerWrapper.Builder<Integer, Integer>() .id("workerA") .worker(new WorkerA()) .callback(new WorkerA()) .param(1) .build(); // 定义任务 B WorkerWrapper wrapperB = new WorkerWrapper.Builder<Integer, Integer>() .id("workerB") .worker(new WorkerB()) .callback(new WorkerB()) .param(2) .build(); // 定义任务 C WorkerWrapper wrapperC = new WorkerWrapper.Builder<Integer, Integer>() .id("workerC") .worker(new WorkerC()) .callback(new WorkerC()) .param(3) .build(); // 提交任务 Async.beginWork(1000, wrapperA, wrapperB, wrapperC);

3. 阻塞等待 - 先串行,后并行

先执行任务 A,然后任务 B 和任务 C 并行执行:

// 定义任务 A WorkerWrapper wrapperA = new WorkerWrapper.Builder<Integer, Integer>() .id("workerA") .worker(new WorkerA()) .callback(new WorkerA()) .param(1) .build(); // 定义任务 B,依赖于任务 A WorkerWrapper wrapperB = new WorkerWrapper.Builder<Integer, Integer>() .id("workerB") .worker(new WorkerB()) .callback(new WorkerB()) .param(2) .depend(wrapperA) .build(); // 定义任务 C,依赖于任务 A WorkerWrapper wrapperC = new WorkerWrapper.Builder<Integer, Integer>() .id("workerC") .worker(new WorkerC()) .callback(new WorkerC()) .param(3) .depend(wrapperA) .build(); // 提交任务 Async.beginWork(1000, wrapperA);

4. 阻塞等待 - 先并行,后串行

任务 B 和任务 C 并行执行,完成后任务 A 执行:

// 定义任务 A WorkerWrapper wrapperA = new WorkerWrapper.Builder<Integer, Integer>() .id("workerA") .worker(new WorkerA()) .callback(new WorkerA()) .param(null) // 参数为任务 B 和任务 C 的结果 .build(); // 定义任务 B WorkerWrapper wrapperB = new WorkerWrapper.Builder<Integer, Integer>() .id("workerB") .worker(new WorkerB()) .callback(new WorkerB()) .param(2) .next(wrapperA) .build(); // 定义任务 C WorkerWrapper wrapperC = new WorkerWrapper.Builder<Integer, Integer>() .id("workerC") .worker(new WorkerC()) .callback(new WorkerC()) .param(3) .next(wrapperA) .build(); // 提交任务 Async.beginWork(1000, wrapperB, wrapperC);

四、主要作用说明

1. 任务编排

灵活的并行与串行组合:asyncTool 支持任意组合多线程的并行和串行任务,开发者可以根据业务需求灵活定义任务的执行顺序。

任务依赖管理:它允许任务之间存在强依赖和弱依赖关系。例如,某些任务必须在其他任务完成后才能执行,而另一些任务则可以在依赖任务中的任意一个或多个完成后执行。

2. 执行监控与回调

全链路回调机制:每个任务在执行过程中,无论成功、失败、超时还是异常,都会触发回调函数。这使得开发者可以实时监控任务的执行状态。

任务跳过回调:即使某些任务被跳过未执行,asyncTool 也会提供回调,方便开发者进行日志记录或异常处理。

3. 异常处理与容错

异常与超时处理:每个任务可以设置超时时间和默认值,当任务执行失败或超时时,会返回默认值,确保整个任务链的稳定性。

独立任务容错:单个任务的失败不会影响其他任务的回调和最终结果的获取,但如果任务依赖的上游任务失败,则当前任务也会失败并返回默认值。

4. 性能优化

低线程设计:asyncTool 采用低线程设计,减少线程的创建和销毁开销。例如,在多个任务依赖关系中,后续任务可以复用前一个任务的线程。

无锁机制:整个框架全程无锁,避免了锁带来的性能开销,提高了并发性能。

5. 结果管理

按顺序返回结果:任务执行完成后,asyncTool 可以按任务添加的顺序返回结果列表,方便开发者进行后续处理。

支持异步回调:除了同步阻塞返回结果外,还支持整个任务组的异步回调,避免阻塞主线程。

6. 线程池管理

线程池共享与独占:支持为每个任务组独享线程池,也可以让所有任务组共享一个线程池,灵活配置资源。

7. 简化开发

封装复杂逻辑:asyncTool 封装了复杂的并发逻辑,使得开发者可以更专注于业务逻辑的实现,而无需深入了解底层的并发机制。

五、注意事项

  • 任务的线程安全:由于任务可能在多个线程中并发执行,需要确保任务的线程安全性。

  • 任务的异常处理:在任务执行过程中可能会出现异常,需要合理地处理异常,避免影响整个应用的运行。

  • 任务的超时设置:合理设置任务的超时时间,避免任务长时间未完成导致资源浪费。

  • 任务的依赖关系:正确配置任务的依赖关系,确保任务按预期顺序执行。

通过以上详细说明和代码示例,你可以在 Spring Boot 项目中灵活使用asyncTool实现复杂的多线程任务编排。

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

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

相关文章

Maven 4 要来了:15 年后,Java 构建工具迎来“彻底重构”

自 2010 年 Maven 3 发布 以来&#xff0c;Maven 对 Java 构建生态的整体支持方式&#xff0c;几乎没有发生过颠覆性的变化。 然而在这 15 年里&#xff0c;Java 世界早已天翻地覆&#xff1a; •模块化成为标配•并行构建成为刚需•云原生与容器化成为主流•JDK 以一年两个大…

收藏!Java程序员转型大模型指南:从入门到落地,抢占AI红利实现薪资跃升

在人工智能&#xff08;AI&#xff09;技术爆发式迭代的当下&#xff0c;传统编程领域正经历前所未有的职业重构。对于深耕Java开发的程序员而言&#xff0c;从熟悉的企业级应用开发、分布式系统搭建&#xff0c;转向如今炙手可热的大模型领域&#xff0c;绝非简单的技术跨界—…

Vlm-ClipJsonl代码

import os import json# 你的实际路径配置&#xff08;无需修改&#xff09; # 脚本所在目录&#xff08;train目录&#xff09; SCRIPT_ROOT os.path.dirname(os.path.abspath(__file__)) # 数据集根路径&#xff08;train/data&#xff09; BASE_PATH os.path.join(SCRIP…

java_ssm114自行车在线租赁系统设计与实现_idea项目源码

目录 具体实现截图自行车在线租赁系统设计与实现摘要 系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 具体实现截图 自行车在线租赁系统设计与实现摘要 自行车在线租赁系统基于SSM&#xff08;SpringSpringM…

瞧瞧别人家的日志打印,那叫一个优雅!

前言这篇文章跟大家一起聊聊打印优雅日志的10条军规&#xff0c;希望对你会有所帮助。第1条&#xff1a;格式统一反例&#xff08;管理看到会扣钱&#xff09;&#xff1a;log.info("start process"); log.error("error happen"); 无时间戳&#xff0c;无上…

java_ssm6专门体检预约管理系统_idea项目源码

目录具体实现截图系统概述技术架构核心功能模块数据库设计项目亮点系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;具体实现截图 系统概述 Java_SSM6专门体检预约管理系统基于SpringSpringMVCMyBatis&#xf…

[特殊字符] 栈与队列基础知识全面解析

一、栈(Stack)理论基础 1.1 栈的基本特性 栈是一种后进先出(LIFO, Last In First Out) 的数据结构,操作只在栈顶进行。 // 栈的基本操作 stack<int> st; st.push(1); // 入栈 st.push(2); int top = st.top(); // 查看栈顶元素:2 st.pop(); // 出栈,…

医疗器械包装运输验证标准:GB/T4857系列标准

一、GB/T 4857系列核心测试标准解析 GB/T 4857《包装 运输包装件基本试验》系列标准涵盖23个部分&#xff0c;针对医疗器械运输场景&#xff0c;以下核心标准构成了全方位的测试体系&#xff1a; &#xff08;一&#xff09;冲击类试验&#xff1a;模拟碰撞风险 跌落试验&am…

java_ssm7特产农产品网上商城的设计与实现_idea项目源码

目录 具体实现截图项目背景与意义技术架构核心功能模块创新点与优势应用价值 系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 具体实现截图 项目背景与意义 随着互联网技术的发展和农村电商的兴起&#xff0…

java_ssm115计算机系统在线考试平台_idea项目源码

目录 具体实现截图计算机系统在线考试平台摘要 系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 具体实现截图 计算机系统在线考试平台摘要 该在线考试平台基于Java SSM框架&#xff08;SpringSpring MVCMyBa…

java_ssm8中药中草药商城 供求信息管理系统_idea项目源码

目录 具体实现截图项目背景与目标技术架构核心功能模块创新与优势适用场景总结 系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 具体实现截图 项目背景与目标 中药中草药商城供求信息管理系统基于Java SSM框…

小迪安全2023-2024|第102天:漏洞发现-漏扫项目篇Poc开发Yaml语法插件一键生成匹配结_笔记|web安全|渗透测试|

第102天&#xff1a;漏洞发现-漏扫项目篇&Poc开发&Yaml语法&插件一键生成&匹配结_笔记 一、漏洞发现—漏扫项目篇&#xfeff;00:15 1. 漏洞扫描工具分类&#xfeff;01:50 综合类工具&#xff1a; BurpSuite&#xff1a;集成化Web应用测试平台&#xff0c;…

C++中string与char的全面解析

一、char(字符) 1.1 基本概念 char 是C++中的基本数据类型,用于表示单个字符。 char c = A; // 单个字符用单引号 char zero = 0; // 字符0,ASCII值为48 char space = ; // 空格字符 char newline = \n; // 转义字符1.2 重要特性 大小:通常1字节(8位)…

如何搭建自动化测试框架?

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 最近好多小伙伴都在说接口自动化测试&#xff0c;那么究竟什么是接口自动化测试呢&#xff1f;让我们一起往下看就知道了&#xff0c;首先我们得先弄清楚下面这…

从Java基础到微服务架构:互联网大厂面试三轮问答实录

从Java基础到微服务架构&#xff1a;互联网大厂面试三轮问答实录 第一轮&#xff1a;核心语言与平台基础 面试官问&#xff1a; Java中HashMap的底层实现原理是什么&#xff1f;JVM如何进行内存管理&#xff1f;能简单介绍下主要的内存区域吗&#xff1f;在Java中&#xff0c;如…

java_ssm2家用二手电器回收系统

目录具体实现截图家用二手电器回收系统摘要系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;具体实现截图 家用二手电器回收系统摘要 随着电子产品更新迭代速度加快&#xff0c;大量二手电器被闲置或废弃&…

java_ssm116课程在线学习评测教学系统智慧学伴服务平台开发_idea项目源码

目录具体实现截图项目概述核心功能技术架构创新点应用价值系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;具体实现截图 项目概述 Java_SSM116课程在线学习评测教学系统智慧学伴服务平台是一个基于SSM&#x…

EasyGBS打造智慧机场一体化智能监管体系

在航空运输业高速发展与智慧化转型的时代背景下&#xff0c;机场作为连接空中与地面的关键枢纽&#xff0c;其运营安全、效率和服务质量面临着前所未有的高标准要求。传统机场监控系统普遍存在“信息孤岛”、智能化程度不足、应急响应滞后等痛点。在这一背景下&#xff0c;Easy…

2026年北京周边诚信的加湿系统专业加盟公司,如何选择?

2026年健康家居市场持续升温,加湿系统作为改善室内环境、提升居住舒适度的核心设备,其加盟赛道也迎来爆发式增长。无论是解决白粉污染、微生物滋生等用户痛点的创新技术,还是覆盖住宅、商业、医疗等多场景的解决方案…

java_ssm3Web的篮球CBA联赛信息管理系统

目录具体实现截图篮球CBA联赛信息管理系统摘要系统所用技术介绍写作提纲源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;具体实现截图 篮球CBA联赛信息管理系统摘要 该系统基于Java SSM&#xff08;SpringSpringMVCMyBatis&#xff09…