大数据量多线程处理并将结果合并成一个List
场景
我有一个List<String> userIds
, 此集合装了10万个用户id, 现在要调用淘宝接口, 将这10万个用户的订单信息s查询出来, 存入到我的系统中
(或者类似的场景, 都可看此文章)
工具函数
/**
* 按千供给
* 将resources, 按照一千一组, 分割成若干组, 一组一组的调用function
* 最终结果合并成一个List
*
* @param resources 原始list
* @param function 批处理函数
* @param async 是否异步
* @param <T> 入参List泛型
* @param <V> 出参List泛型
* @return 最终结果
*/
public static <T, V> List<V> supplyByThousand(List<T> resources, Function<List<T>, List<V>> function, boolean async) {
if (CollUtil.isEmpty(resources)) {
return Collections.emptyList();
}
List<List<T>> groups = CollUtil.split(resources, DEFAULT_BATCH_SIZE);
if (async) {
return groups.stream().parallel().flatMap(group -> function.apply(group).stream()).collect(Collectors.toList());
} else {
return groups.stream().flatMap(group -> function.apply(group).stream()).collect(Collectors.toList());
}
}
使用
List<TaobaoOrder> orders = Lambdas.supplyByThousand(userIds, idGroup -> taobaoTemplate.findByUserIds(idGroup), async);
// 共查询出30万条订单信息
这样你就拿到了10万用户的所有订单信息.
额外知识
如果你想一个一个用户的查询, 可参考该函数中的.stream().parallel()
并行流机制
userIds.stream()
.parallel()
.flatMap(userId->taobaoTemplate.findByUserId(userId).stream())
.collect(Collectors.toList())
注意:
像这种大量多线程的场景, 只适合I/O场景(调数据库, 调http接口, 调rpc, 读文件等…)
如果你的场景是做数学运算, 金额统计等CPU场景, 则多线程会降低效率, 建议直接for循环.