项目场景:
项目场景:调用第三方提供的接口去获取 List 中用户的组信息。
问题描述
需要拿用户的 id 去调用第三方接口,成功调用一次需要 0.3s 左右,当有 1000 个用户时,就需要花费 0.3 * 1000s = 5min,页面就会一直加载那么久。之前是通过 for 循环 list 去调用接口的,代码如下:
// 当 list 长度为 1000时,则需要循环 1000次
for(User user : list) {
loadUserGroups(user);
}
解决方案:
通过多线程的方式去处理,话不多说直接上代码:
// 定义一个线程池
private static final ExecutorService loadUserGroupsExecutor = Executors.newFixedThreadPool(20);
public Map<String, List<UserGroup>> loadAllUserGroups() {
Map<String, List<UserGroup>> userGroups = new ConcurrentHashMap<>();
List<User> users = listUsers();
int size = users.size();
long startTime = System.currentTimeMillis();
if (size > 200) {
List<List<User>> partition = Lists.partition(users, 200);
List<CompletableFuture> results = new ArrayList<>();
for (List<User> subList : partition) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
loadUserGroups(userGroups, subList);
return "";
}, loadUserGroupsExecutor);
results.add(future);
}
CompletableFuture.allOf(results.toArray(results.toArray(new CompletableFuture[partition.size()]))).join();
} else {
loadUserGroups(userGroups, users);
}
log.info("loadAllUserGroups cost {}", System.currentTimeMillis() - startTime);
return userGroups;
}