java8 stream并发处理分批操作

使用场景:

查询数据量很大的时候需要分批查询

在不并发操作的情况下,假设数据总量为 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

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值