当前位置: 首页 > 软件库 > 程序开发 > 常用工具包 >

asyncTool

多线程编排一站式解决方案
授权协议 Apache
开发语言 Java
所属分类 程序开发、 常用工具包
软件类型 开源软件
地区 国产
投 递 者 柯学
操作系统 跨平台
开源组织 京东
适用人群 未知
 软件概览

解决任意的多线程并行、串行、阻塞、依赖、回调的并行框架,可以任意组合各线程的执行顺序,带全链路执行结果回调。多线程编排一站式解决方案。来自于京东主 App 后台。

该框架目前正在京东 App 后台接受苛刻、高并发、海量用户等复杂场景业务的检验测试,随时会根据实际情况发布更新和 bugFix。

并行常见的场景

1. 客户端请求服务端接口,该接口需要调用其他N个微服务的接口

譬如 请求我的订单,那么就需要去调用用户的rpc、商品详情的rpc、库存rpc、优惠券等等好多个服务。同时,这些服务还有相互依赖关系,譬如必须先拿到用户的某个字段后,再去某rpc服务请求数据。 最终全部获取完毕后,或超时了,就汇总结果,返回给客户端。

2. 并行执行N个任务,后续根据这1-N个任务的执行结果来决定是否继续执行下一个任务

如用户可以通过邮箱、手机号、用户名登录,登录接口只有一个,那么当用户发起登录请求后,我们需要并行根据邮箱、手机号、用户名来同时查数据库,只要有一个成功了,都算成功,就可以继续执行下一步。而不是先试邮箱能否成功、再试手机号……

再如某接口限制了每个批次的传参数量,每次最多查询10个商品的信息,我有45个商品需要查询,就可以分5堆并行去查询,后续就是统计这5堆的查询结果。就看你是否强制要求全部查成功,还是不管有几堆查成功都给客户做返回

再如某个接口,有5个前置任务需要处理。其中有3个是必须要执行完毕才能执行后续的,另外2个是非强制的,只要这3个执行完就可以进行下一步,到时另外2个如果成功了就有值,如果还没执行完,就是默认值。

3. 需要进行线程隔离的多批次任务

如多组任务, 各组任务之间彼此不相关,每组都需要一个独立的线程池,每组都是独立的一套执行单元的组合。有点类似于hystrix的线程池隔离策略。

4. 单机工作流任务编排

5. 其他有顺序编排的需求

并行场景之核心——任意编排

1 多个执行单元的串行请求

输入图片说明

2 多个执行单元的并行请求

输入图片说明

3 阻塞等待,串行的后面跟多个并行

输入图片说明

4 阻塞等待,多个并行的执行完毕后才执行某个

输入图片说明

5 串并行相互依赖

输入图片说明

6 复杂场景

输入图片说明

并行场景可能存在的需求之——每个执行结果的回调

传统的Future、CompleteableFuture一定程度上可以完成任务编排,并可以把结果传递到下一个任务。如CompletableFuture有then方法,但是却无法做到对每一个执行单元的回调。譬如A执行完毕成功了,后面是B,我希望A在执行完后就有个回调结果,方便我监控当前的执行状况,或者打个日志什么的。失败了,我也可以记录个异常信息什么的。

此时,CompleteableFuture就无能为力了。

我的框架提供了这样的回调功能。并且,如果执行异常、超时,可以在定义这个执行单元时就设定默认值。

并行场景可能存在的需求之——执行顺序的强依赖和弱依赖

如上图的3,A和B并发执行,最后是C。

有些场景下,我们希望A和B都执行完毕后,才能执行C,CompletableFuture里有个allOf(futures...).then()方法可以做到。

有些场景下,我们希望A或者B任何一个执行完毕,就执行C,CompletableFuture里有个anyOf(futures...).then()方法可以做到。

我的框架同样提供了类似的功能,通过设定wrapper里的addDepend依赖时,可以指定依赖的任务是否must执行完毕。如果依赖的是must要执行的,那么就一定会等待所有的must依赖项全执行完毕,才执行自己。

如果依赖的都不是must,那么就可以任意一个依赖项执行完毕,就可以执行自己了。

注意:这个依赖关系是有必须和非必须之分的,还有一个重要的东西是执行单元不能重复执行。譬如图4,如果B执行完毕,然后执行了A,此时C终于执行完了,然后也到了A,此时就会发现A已经在执行,或者已经完毕(失败),那么就不应该再重复执行A。

还有一种场景,如下图,A和D并行开始,D先执行完了,开始执行Result任务,此时B和C都还没开始,然后Result执行完了,虽然B和C都还没执行,但是已经没必要执行了。B和C这些任务是可以被跳过的,跳过的原则是他们的NextWrapper已经有结果了或者已经在执行了。我提供了checkNextWrapperResult方法来控制,当后面的任务已经执行了,自己还要不要执行的逻辑控制。当然,这个控制仅限于nextWrapper只有一个时才有成立。

输入图片说明

并发场景可能存在的需求之——依赖上游的执行结果作为入参

譬如A-B-C三个执行单元,A的入参是String,出参是int,B呢它需要用A的结果作为自己的入参。也就是说A、B并不是独立的,而是有结果依赖关系的。

在A执行完毕之前,B是取不到结果的,只是知道A的结果类型。

那么,我的框架也支持这样的场景。可以在编排时,就取A的结果包装类,作为B的入参。虽然此时尚未执行,必然是空,但可以保证A执行完毕后,B的入参会被赋值。

并发场景可能存在的需求之——全组任务的超时

一组任务,虽然内部的各个执行单元的时间不可控,但是我可以控制全组的执行时间不超过某个值。通过设置timeOut,来控制全组的执行阈值。

并发场景可能存在的需求之——高性能、低线程数

该框架全程无锁,不依靠线程锁来保证顺序。

创建线程量少。输入图片说明 如这样的,A会运行在B、C执行更慢的那个单元的线程上,而不会额外创建线程。

asyncTool特点

解决任意的多线程并行、串行、阻塞、依赖、回调的并发框架,可以任意组合各线程的执行顺序,带全链路回调和超时控制。

其中的A、B、C分别是一个最小执行单元(worker),可以是一段耗时代码、一次Rpc调用等,不局限于你做什么。

该框架可以将这些worker,按照你想要的各种执行顺序,加以组合编排。最终得到结果。

并且,该框架 为每一个worker都提供了执行结果的回调和执行失败后自定义默认值 。譬如A执行完毕后,A的监听器会收到回调,带着A的执行结果(成功、超时、异常)。

根据你的需求,将各个执行单元组合完毕后,开始在主线程执行并阻塞,直到最后一个执行完毕。并且 可以设置全组的超时时间 。

该框架支持后面的执行单元以前面的执行单元的结果为自己的入参 。譬如你的执行单元B的入参是ResultA,ResultA就是A的执行结果,那也可以支持。在编排时,就可以预先设定B或C的入参为A的result,即便此时A尚未开始执行。当A执行完毕后,自然会把结果传递到B的入参去。

快速开始

点此开启实战

 相关资料
  • 本文向大家介绍Linux多线程编程(一),包括了Linux多线程编程(一)的使用技巧和注意事项,需要的朋友参考一下 一、什么是线程?       线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。 二、什

  • 我在尝试停止运行多个线程的程序时遇到了问题,所有运行的线程都试图找到相同的解决方案,但一旦一个线程找到了解决方案,所有其他线程都将停止。 在main方法中,我创建了一个线程组,使用for循环向其中添加线程并启动它们 在实现Runnable的类中,我很难找出如何使其实现,以便一旦其中一个线程找到解决方案,所有线程都将停止。最终发生的情况是,要么其他线程继续运行,有时这些线程会相互中断并相互覆盖。

  • 本文向大家介绍详解Java多线程编程中CountDownLatch阻塞线程的方法,包括了详解Java多线程编程中CountDownLatch阻塞线程的方法的使用技巧和注意事项,需要的朋友参考一下 直译过来就是倒计数(CountDown)门闩(Latch)。倒计数不用说,门闩的意思顾名思义就是阻止前进。在这里就是指 CountDownLatch.await() 方法在倒计数为0之前会阻塞当前线程。

  • 打开 ACTS IDE 在 Package 视图下,右键含 @Test 注解的函数名,ACTS 功能 -> 修改测试用例,如下图: 编写测试数据 准备入参 根据被测的接口方法的入参(类型、顺序、数量)正确准备入参数据,简单类型包括 String、Date、Integer、Float、Double、Long、Short、Byte(包含其对应的基本类型,即 int、float 等);复杂类型为 Lis

  • 这本书最初是为北京亚嵌教育研究中心的嵌入式 Linux 系统工程师就业班课程量身定做的教材之一。

  • 其实创建线程之后,线程并不是始终保持一个状态的,其状态大概如下: New 创建 Runnable 就绪。等待调度 Running 运行 Blocked 阻塞。阻塞可能在 Wait Locked Sleeping Dead 消亡 线程有着不同的状态,也有不同的类型。大致可分为: 主线程 子线程 守护线程(后台线程) 前台线程 简单了解完这些之后,我们开始看看具体的代码使用了。 1、线程的创建 Pyt