vertx中异步任务实现串行/并行执行以及回调

本文介绍了如何在Vertx框架中实现异步任务的串行和并行执行。针对串行执行,通过递归或者封装执行器实现任务顺序执行,并在所有任务完成后提供回调。并行执行则利用Future和回调机制,确保所有任务执行完毕后通知用户,并汇总执行结果。同时,文章提供了具体的设计和实现代码,以及测试用例。
摘要由CSDN通过智能技术生成

简述

串行执行异步任务

使用vertx框架编程的过程中,经常会遇到这种情况:需要处理一组异步任务,而且我们希望它们可以按照顺序执行下去,并且当它们全部执行完了得到通知,而且有时候也需要控制,当一个执行失败,后面的任务是否需要继续执行。这个就是按照顺序去执行异步任务,解决方案当然就是递归了,这个在我很早的博客当中已经写过了。多个异步请求保证执行顺序:用递归。但是呢,随着功能的一步步增多,这种需求是特别多的,你需要写大量的递归,我写着都烦了,那能不能封装一个执行器,替我们来递归执行任务呢,我们只需要按顺序提交并且提供一个回调处理器呢,答案是有的。

并行执行异步任务

另外一种场景:也是需要处理一组异步任务,但是它们是无序的,无序执行异步任务本身是很简单的,用普通的for循环就行了,但是最难的地方在于,它没有办法回调,就是不知道什么时候全部执行了。我们的需求就是需要执行一个回调器,全部执行完了以后通知我,并且告诉我,有哪些失败了,我再进一步处理。我把这个实现了以后,又去思考了上面的场景,也顺便实现了一下。

并行执行任务设计和实现

并行设计

想要实现这个,就是从下面几个方面去入手就行了:

  1. vertx提交的异步任务,真正的执行都会在另外一个线程里面(包括本身线程),至于说最终线程怎么执行的,我们其实不关心,关心的就是把这些任务一次性全部提交了,这个容易,for循环遍历一下就行了。
  2. 我们重点想要的是一个通知,全部执行完成的通知,那也就是应该当每一个任务执行完成以后,都应该告诉执行器,我执行完了,不管失败还是成功,然后执行器再去校验是否全部都通知过了,以此来判断是否发出最后的通知。那也就是说,对于提交的每一个任务,都有一个Future(在vertx里面代表一个异步操作的结果),用来表示它的状态,并且当完成以后,它的回调处理器就应该去校验所有的Future。
  3. 当所有都执行完毕了,我们就要去回调,回调什么呢?一个处理器,由用户提供,并且也是一个异步结果。
  4. 还有就是执行结果了,要么成功要么失败。暂时就定义成:全部成功算成功,一个失败就算失败。如果有多个失败的,但是我们只能抛一个异常,那就在一个异常里面把所有的错误情况都添加进去。

并行实现

根据上面的思考,就有了下面的实现,直接贴代码了。

/**
 * @Description 并行异步任务执行器
 * 用来解决场景:处理一组异步任务,任务之间没有顺序,但是希望在执行全部结束以后,进行回调。
 * 重点是提供回调的功能。因为普通的for循环就能够不按顺序执行它们,但是没有回调。
 * 
 **/
public class ParallelAsyncTaskExecutor implements AsyncResult<Void> {
   
    /**
     * 存储所有任务
     * key:任务。
     * value:是任务对应的异步结果。
     */
    private final Map<Handler<Future<Void>>, Future<Void>> tasks;
    private Handler<AsyncResult<Void>> handler;
    public ParallelAsyncTaskExecutor() {
   
        this.tasks = new HashMap<>();
    }

    /**
     * 添加一个异步任务,给这个任务挂上一个处理器,当任务执行以后就去校验是否所有的都执行完了。
     * @param handler
     */
    public void addAsyncTask(Handler<Future<Void>> handler){
   
        Future<Void> future = Future.future();
        future.setHandler(futureHandler -> {
   
            checkCallHandler();
        });
        this.tasks.put(handler, future);
    }

    /**
     * 检查并调用处理器
     */
    private void checkCallHandler() {
   
        if (isComplete()) {
   
            callHandler();
        }
    }

    private void callHandler(){
   
        if (handler != null) {
   
            handler.handle(this);
            handler = null;
        }
    }

    /**
     * 是否所有任务完成了
     * 挨个判断每个任务的结果。
     * @return
     */
    public boolean isComplete() {
   
        if (tasks.isEmpty()) {
   
            return false;
        }
        return tasks.values().stream().allMatch(future -> {
   
            return future.isComplete();
        });
    }

    /**
     * 执行启动。
     * for循环执行
     */
    public void start() {
   
        if (this.tasks.isEmpty()) {
   
            callHandler();
            return;
        }
        this.tasks.forEach((handler, future) -> {
   
            try {
   
                handler.handle(future)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值