使用场景:
查询数据量很大的时候需要分批查询
在不并发操作的情况下,假设数据总量为 10万,每次查询500条数据,每次查询耗时100ms,则总耗时最少要20s,这样是相当慢的
使用java8的stream可以多线程查询数据
两者耗时对比如下
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @desc java8 流的方式并发处理分批操作
* @date 2021/1/6
*/
public class ParallelTest {
public static void main(String[] args) {
//业务数据
List<String> dataList=new ArrayList<>();
for (int i = 0; i < 100000; i++) {
dataList.add(i+"");
}
int num=500;
long startTime = System.currentTimeMillis();
List<String> result=new ArrayList<>();
try {
result = Stream.iterate(0, i -> i + 1).limit(dataList.size() / num + 1).parallel().map(i -> {
//获取每一批的数据
List<String> perList = dataList.parallelStream().skip(i * num)
.limit(num)
.collect(Collectors.toList());
//业务处理
return queryThisData(perList,i);
}).filter(o -> Objects.nonNull(o))
.flatMap(Collection::parallelStream)
.collect(Collectors.toList());
} catch (Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println("并发批量处理耗时:"+(endTime-startTime)+" 数据总数:"+result.size());
//不并发分批
List<String> result2=new ArrayList<>();
List<List<String>> parList=new ArrayList<>();
int size = dataList.size() % num == 0 ? (dataList.size() / num) : (dataList.size() / num + 1);
for (int i = 0; i < size ; i++) {
List<String> list=new ArrayList<>();
for (int j=i*num;j<num*(i+1);j++){
list.add(dataList.get(j));
}
parList.add(list);
}
for (int i = 0; i < parList.size(); i++) {
result2.addAll(queryThisData(parList.get(i),i));
}
System.out.println("不并发批量处理耗时:"+(System.currentTimeMillis()-endTime)+" 数据总数:"+result2.size());
}
private static List<String> queryThisData(List<String> perList,int i) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return perList;
}
}
输出结果:
并发批量处理耗时:2784 数据总数:100000
不并发批量处理耗时:20122 数据总数:100000
也可以用ExecutorService实现
两者性能比较参考:
https://www.cnblogs.com/metoy/p/4323910.html