1、前言

在实际开发小程序页面过程中,一个接口可能要查询用户信息,配置信息等页面信息。在接收到页面请求后,后台会先查询用户信息,查完后再查询配置信息,这样串行执行会导致速度变慢。我们可以通过并发编程来并行查询这些信息。

2、并行代码

首先,我们先看看串行代码,代码从上到下一次执行,会增加查询时间

public void queryAllInfo(String userId){

        //查询用户信息
        User userInfo = getUserInfo(userId);
        //查询配置信息
        Config configInfo = getConfigInfo(userId);
        //查询文件信息
        FileVo fileVo = getFileVo(userId);
    }

我们不采用上述逻辑,我们是用并行逻辑,代码如下

public void queryAllInfoSync(String userId){
        //构建线程池
        ExecutorService executor  = Executors.newFixedThreadPool(10);
        CompletionService<Object> baseDTOCompletionService = new ExecutorCompletionService<Object>(executor);

        //创建任务
        Callable task1 = ()->{
            User userInfo = getUserInfo(userId);
            BaseRspDTO<User> result = new BaseRspDTO<>();
            result.setKey("userInfo");
            result.setData(userInfo);
            return result;
        };
        Callable task2 = ()->{
            Config configInfo = getConfigInfo(userId);
            BaseRspDTO<Config> result = new BaseRspDTO<>();
            result.setKey("configInfo");
            result.setData(configInfo);
            return result;
        };
        Callable task3 = ()->{
            FileVo fileVo = getFileVo(userId);
            BaseRspDTO<FileVo> result = new BaseRspDTO<>();
            result.setKey("fileVo");
            result.setData(fileVo);
            return result;
        };
        baseDTOCompletionService.submit(task1);
        baseDTOCompletionService.submit(task2);
        baseDTOCompletionService.submit(task3);

        //获取执行结果

        try {
            //因为提交了3个任务,所以获取结果次数是3
            for (int i = 0; i < 3; i++) {
                Future<Object> baseRspDTOFuture = baseDTOCompletionService.poll(1, TimeUnit.SECONDS);
                BaseRspDTO baseRspDTO = (BaseRspDTO) baseRspDTOFuture.get();
                if ("userInfo".equals(baseRspDTO.getKey())) {
                    User user = (User) baseRspDTO.getData();
                    System.out.println("用户数据"+user);
                } else if ("configInfo".equals(baseRspDTO.getKey())) {
                    Config data = (Config) baseRspDTO.getData();
                    System.out.println("配置信息"+data);
                } else if ("fileVo".equals(baseRspDTO.getKey())) {
                    FileVo file = (FileVo) baseRspDTO.getData();
                    System.out.println("文件信息"+file);
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }

注意:BaseRspDTO类是一个我们自定义的类,主要是因为并行执行结果,我们不确定是什么类型,所有只能预先存入一个标识,后面方便强转结果类型。代码如下

@Data
public class BaseRspDTO<T extends Object> {

    //区分是DTO返回的唯一标记,比如是UserInfoDTO还是BannerDTO
    private String key;
    //返回的data
    private T data;

3、总结

上述是我看了网上的资料后写的一个方法,亲测可用,最后,祝大家520快乐!