多个CompletableFuture重复写如何简化,封装,复用,让同事们耳目一新的写法,这里给你答案

这段时间接到一个校验的需求改动,最开始拿到的代码大致上逻辑思路是如下的,可以分析出来他这个当前已经有了3个校验了,我本次的需求是再加1个校验且本次的校验checkData函数是不能满足的

import cn.hutool.core.collection.CollectionUtil;
import com.example.demo.resp.ResponseDataModel;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * @author Mikey
 * @version 1.0
 * @date 2023/5/10 16:14
 * @description 校验Controller案例
 */
@RestController
@Slf4j
@RequestMapping("/check")
public class CheckRuleController {

    @ApiOperation(value = "校验数据接口", httpMethod = "GET")
    @GetMapping("/checkAllData")
    public ResponseDataModel checkAllData() throws ExecutionException, InterruptedException {
        // 校验1
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            long l1 = System.currentTimeMillis();
            System.out.println("任务1启动!  =====>" + l1);
            // 校验1业务逻辑校验代码
            String result = checkData("1");
            long l2 = System.currentTimeMillis();
            System.out.println("任务1结束,耗时:!  =====>" + (l2 - l1));
            return result;
        });
        // 校验2
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            long l1 = System.currentTimeMillis();
            System.out.println("任务2启动!  =====>" + l1);
            // 校验2业务逻辑校验代码
            String result = checkData("2");
            long l2 = System.currentTimeMillis();
            System.out.println("任务2结束,耗时:!  =====>" + (l2 - l1));
            return result;
        });

        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            long l1 = System.currentTimeMillis();
            System.out.println("任务3启动!  =====>" + l1);
            // 校验3业务逻辑校验代码
            String result = checkData("3");
            long l2 = System.currentTimeMillis();
            System.out.println("任务3结束,耗时:!  =====>" + (l2 - l1));
            return result;
        });
        List<String> futureList = new ArrayList<>();
        futureList.add(future1.get());
        futureList.add(future2.get());
        futureList.add(future3.get());
        List<String> resultList = Arrays.stream(futureList.toArray(new String[futureList.size()])).collect(Collectors.toList());
        return CollectionUtil.isEmpty(resultList) ? ResponseDataModel.ok() : ResponseDataModel.ok(resultList);
    }

    /**
     * 各类型规则进行校验
     * @param type
     * @return
     */
    private String checkData(String type){
        // 伪代码 doSth为你的业务逻辑代码
        String result = StringUtils.EMPTY;
        switch (type){
            case "1":
                //result = doSth1...
                result = "1";
                break;
            case "2":
                //result =  doSth2...
                result = "2";
                break;
            default:
                //result =  doSth default...
                result = "default";
                break;
        }
        return result;
    }

}

按照如上代码思路,再加一个校验或者更多的校验代码就会向如下趋势演化

import cn.hutool.core.collection.CollectionUtil;
import com.example.demo.resp.ResponseDataModel;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * @author Mikey
 * @version 1.0
 * @date 2023/5/10 16:14
 * @description 校验Controller案例
 */
@RestController
@Slf4j
@RequestMapping("/check")
public class CheckRuleController {

    @ApiOperation(value = "校验数据接口", httpMethod = "GET")
    @GetMapping("/checkAllData")
    public ResponseDataModel checkAllData() throws ExecutionException, InterruptedException {
        // 校验1
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            long l1 = System.currentTimeMillis();
            System.out.println("任务1启动!  =====>" + l1);
            // 校验1业务逻辑校验代码
            String result = checkData("1");
            long l2 = System.currentTimeMillis();
            System.out.println("任务1结束,耗时:!  =====>" + (l2 - l1));
            return result;
        });
        // 校验2
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            long l1 = System.currentTimeMillis();
            System.out.println("任务2启动!  =====>" + l1);
            // 校验2业务逻辑校验代码
            String result = checkData("2");
            long l2 = System.currentTimeMillis();
            System.out.println("任务2结束,耗时:!  =====>" + (l2 - l1));
            return result;
        });

        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
            long l1 = System.currentTimeMillis();
            System.out.println("任务5启动!  =====>" + l1);
            // 校验3业务逻辑校验代码
            String result = checkData("3");
            long l2 = System.currentTimeMillis();
            System.out.println("任务5结束,耗时:!  =====>" + (l2 - l1));
            return result;
        });
        // 校验4
        CompletableFuture<String> future4 = CompletableFuture.supplyAsync(() -> {
            long l1 = System.currentTimeMillis();
            System.out.println("任务4启动!  =====>" + l1);
            // 校验4业务逻辑校验代码
            String result = newCheckData();
            long l2 = System.currentTimeMillis();
            System.out.println("任务4结束,耗时:!  =====>" + (l2 - l1));
            return result;
        });
        // 校验5
        CompletableFuture<String> future5 = CompletableFuture.supplyAsync(() -> {
            long l1 = System.currentTimeMillis();
            System.out.println("任务5启动!  =====>" + l1);
            // 校验5业务逻辑校验代码
            String result = otherCheckData();
            long l2 = System.currentTimeMillis();
            System.out.println("任务5结束,耗时:!  =====>" + (l2 - l1));
            return result;
        });
        // 校验6
        CompletableFuture<String> future6 = CompletableFuture.supplyAsync(() -> {
            long l1 = System.currentTimeMillis();
            System.out.println("任务6启动!  =====>" + l1);
            // 校验6业务逻辑校验代码
            String result = otherCheckData();
            long l2 = System.currentTimeMillis();
            System.out.println("任务6结束,耗时:!  =====>" + (l2 - l1));
            return result;
        });
        List<String> futureList = new ArrayList<>();
        // 收集异步执行结果
        futureList.add(future1.get());
        futureList.add(future2.get());
        futureList.add(future3.get());
        futureList.add(future4.get());
        futureList.add(future5.get());
        futureList.add(future6.get());
        List<String> resultList = Arrays.stream(futureList.toArray(new String[futureList.size()])).collect(Collectors.toList());
        return CollectionUtil.isEmpty(resultList) ? ResponseDataModel.ok() : ResponseDataModel.ok(resultList);
    }

    /**
     * 各类型规则进行校验
     * @param type
     * @return
     */
    private String checkData(String type){
        // 伪代码 doSth为你的业务逻辑代码
        String result = StringUtils.EMPTY;
        switch (type){
            case "1":
                //result = doSth1...
                result = "1";
                break;
            case "2":
                //result =  doSth2...
                result = "2";
                break;
            default:
                //result =  doSth default...
                result = "default";
                break;
        }
        return result;
    }

    /**
     * 新业务校验规则
     * @return
     */
    private String newCheckData(){
        return "新1";
    }

    /**
     * 其他业务校验规则
     * @return
     */
    private String otherCheckData(){
        return "更多其他校验";
    }
}

到这里,大多数同学们应该都会发起提问,在这里插入图片描述
每次加个校验任务都得写一次CompletableFuture.supplyAsync()、FutureList.add(),代码量虽然蹭蹭往上涨,但都是无效代码,虽然实现了,但我们不做写屎山的攻城狮在这里插入图片描述
接下来进入优化步骤,这边演化的是最终的优化代码版本,其中碰到了很多坎,也是请教了朋友一步步改造,才完成如下代码版本

第一步,每一个校验都要加一个异步,CompletableFuture是一个重复的代码,思考有没办法扔到循环里面,用循环完成异步部署任务
PS:CompletableFuture.supplyAsync(supplier, threadPoolExecutor)可以改用采用自定义线程池配置

    /**
     * 部署所有异步任务
     * @param suppliers
     * @return
     */
    public List<CompletableFuture<String>> buildCompletableFutureList(Supplier... suppliers) {
        List<CompletableFuture<String>> futureList = new ArrayList<>();
        for (Supplier supplier : suppliers) {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(supplier);
            futureList.add(future);
        }
        return futureList;
    }

第二步,根据第一步封装异步部署任务,需要提供参数Supplier的方法,对各校验函数进行改造

 /**
     * 各类型规则进行校验
     *
     * @param type
     * @return
     */
    private Supplier<String> checkData(String type) {
        return () -> {
            // 伪代码 doSth为你的业务逻辑代码
            String result = StringUtils.EMPTY;
            switch (type) {
                case "1":
                    //result = doSth1...
                    result = "1";
                    break;
                case "2":
                    //result =  doSth2...
                    result = "2";
                    break;
                default:
                    //result =  doSth default...
                    result = "default";
                    break;
            }
            return result;
        };
    }

第三步,收集各异步执行结果改造

/**
     * 获取所有异步任务执行结果
     * @param futureList
     * @return
     */
    public List<String> getFutureResultList(List<CompletableFuture<String>> futureList){
        // 收集各异步校验任务
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()]));
        // 等待所有任务执行结果
        allFutures.join();
        // 获取所有任务执行结果
        List<String> resultList = new ArrayList<>();
        for(CompletableFuture<String> future: futureList){
            resultList.add(future.join());
        }
        return resultList;
    }

按上述步骤整合后的代码,整体代码更为简洁,提高可读性、代码复用性

import cn.hutool.core.collection.CollectionUtil;
import com.example.demo.resp.ResponseDataModel;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @author Mikey
 * @version 1.0
 * @date 2023/5/10 16:14
 * @description 校验Controller案例
 */
@RestController
@Slf4j
@RequestMapping("/check")
public class CheckRuleController {

    @ApiOperation(value = "校验数据接口", httpMethod = "GET")
    @GetMapping("/checkAllData")
    public ResponseDataModel checkAllData() throws ExecutionException, InterruptedException {
        List<Supplier<String>> suppliers = new ArrayList<>();
        // 校验1
        suppliers.add(checkData("1"));
        // 校验2
        suppliers.add(checkData("2"));
        // 校验3
        suppliers.add(checkData("3"));
        // 校验4
        suppliers.add(newCheckData());
        // 校验5
        suppliers.add(otherCheckData());
        // 校验6
        suppliers.add(otherCheckData());
        // 部署各异步校验任务
        List<CompletableFuture<String>> futureList = buildCompletableFutureList(suppliers.toArray(new Supplier[suppliers.size()]));
        // 获取所有异步任务执行结果
        List<String> resultList = getFutureResultList(futureList);
        // 响应服务端结果
        return CollectionUtil.isEmpty(resultList) ? ResponseDataModel.ok() : ResponseDataModel.ok(resultList);
    }

    /**
     * 获取所有异步任务执行结果
     * @param futureList
     * @return
     */
    public List<String> getFutureResultList(List<CompletableFuture<String>> futureList){
        // 收集各异步校验任务
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()]));
        // 等待所有任务执行结果
        allFutures.join();
        // 获取所有任务执行结果
        List<String> resultList = new ArrayList<>();
        for(CompletableFuture<String> future: futureList){
            resultList.add(future.join());
        }
        return resultList;
    }

    /**
     * 部署所有异步任务
     * @param suppliers
     * @return
     */
    public List<CompletableFuture<String>> buildCompletableFutureList(Supplier... suppliers) {
        List<CompletableFuture<String>> futureList = new ArrayList<>();
        for (Supplier supplier : suppliers) {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(supplier);
            futureList.add(future);
        }
        return futureList;
    }

    /**
     * 各类型规则进行校验
     *
     * @param type
     * @return
     */
    private Supplier<String> checkData(String type) {
        return () -> {
            // 伪代码 doSth为你的业务逻辑代码
            String result = StringUtils.EMPTY;
            switch (type) {
                case "1":
                    //result = doSth1...
                    result = "1";
                    break;
                case "2":
                    //result =  doSth2...
                    result = "2";
                    break;
                default:
                    //result =  doSth default...
                    result = "default";
                    break;
            }
            return result;
        };
    }

    /**
     * 新业务校验规则
     *
     * @return
     */
    private Supplier<String> newCheckData() {
        return () -> {
            return "新1";
        };
    }

    /**
     * 其他业务校验规则
     *
     * @return
     */
    private Supplier<String> otherCheckData() {
        return () -> {
            return "更多其他校验";
        };
    }
}

所谓“道生一,一生二,二生三,三生万物”,还可以考虑几个封装的函数由于使用的业务场景不同,参数类型和数据类型也可能不同,更换为泛型,这样才能让自身实力更加强大
在这里插入图片描述

import cn.hutool.core.collection.CollectionUtil;
import com.example.demo.resp.ResponseDataModel;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @author Mikey
 * @version 1.0
 * @date 2023/5/10 16:14
 * @description 校验Controller案例
 */
@RestController
@Slf4j
@RequestMapping("/check")
public class CheckRuleController {

    @ApiOperation(value = "校验数据接口", httpMethod = "GET")
    @GetMapping("/checkAllData")
    public ResponseDataModel checkAllData() throws ExecutionException, InterruptedException {
        List<Supplier> suppliers = new ArrayList<>();
        // 校验1
        suppliers.add(checkData("1"));
        // 校验2
        suppliers.add(checkData("2"));
        // 校验3
        suppliers.add(checkData("3"));
        // 校验4
        suppliers.add(newCheckData());
        // 校验5
        suppliers.add(otherCheckData());
        // 校验6
        suppliers.add(otherCheckData());
        // 部署各异步校验任务
        List<CompletableFuture<String>> futureList = buildCompletableFutureList(suppliers.toArray(new Supplier[suppliers.size()]));
        // 获取所有异步任务执行结果
        List<String> resultList = getFutureResultList(futureList);
        // 响应服务端结果
        return CollectionUtil.isEmpty(resultList) ? ResponseDataModel.ok() : ResponseDataModel.ok(resultList);
    }

    /**
     * 获取所有异步任务执行结果
     *
     * @param futureList
     * @return
     */
    public <T> List<T> getFutureResultList(List<CompletableFuture<T>> futureList) {
        // 收集各异步校验任务
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()]));
        // 等待所有任务执行结果
        allFutures.join();
        // 获取所有任务执行结果
        List<Object> resultList = new ArrayList<>();
        for (CompletableFuture<T> future : futureList) {
            resultList.add(future.join());
        }
        return (List<T>) resultList;
    }

    /**
     * 部署所有异步任务
     *
     * @param suppliers
     * @return
     */
    public <T> List<CompletableFuture<T>> buildCompletableFutureList(Supplier<T>... suppliers) {
        List<CompletableFuture<T>> futureList = new ArrayList<>();
        for (Supplier supplier : suppliers) {
            CompletableFuture<T> future = CompletableFuture.supplyAsync(supplier);
            futureList.add(future);
        }
        return futureList;
    }

    /**
     * 各类型规则进行校验
     *
     * @param type
     * @return
     */
    private <T> Supplier<T> checkData(String type) {
        return () -> {
            // 伪代码 doSth为你的业务逻辑代码
            String result = StringUtils.EMPTY;
            switch (type) {
                case "1":
                    //result = doSth1...
                    result = "1";
                    break;
                case "2":
                    //result =  doSth2...
                    result = "2";
                    break;
                default:
                    //result =  doSth default...
                    result = "default";
                    break;
            }
            return (T) result;
        };
    }

    /**
     * 新业务校验规则
     *
     * @return
     */
    private <T> Supplier<T> newCheckData() {
        return () -> {
            return (T) "新1";
        };
    }

    /**
     * 其他业务校验规则
     *
     * @return
     */
    private <T> Supplier<T> otherCheckData() {
        return () -> {
            return (T) "更多其他校验";
        };
    }
}

最后就是运行代码,求证自身之道时刻
在这里插入图片描述
如果喜欢我写的文章的同学们,求三连
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值