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快乐!