避坑 | Java8使用并行流(ParallelStream)注意事项

示例分析

/**
 * 避坑 | Java8使用并行流(ParallelStream)注意事项
 *
 * @author WH.L
 * @date 2020/12/26 17:14
 */
public class TestParallelStream {
    public static void main(String[] args) {
        printFun();
    }
    public static void printFun() {
        List<Integer> integersList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            integersList.add(i);
        }
        //普通集合 存储
        List<Integer> parallelStorage = new ArrayList<>();
        //同步集合 存储
        List<Integer> parallelStorage2 = Collections.synchronizedList(new ArrayList<>());
        //通过并行流存入普通集合parallelStorage中
        integersList
                .parallelStream()
                .filter(i -> i % 2 == 0)
                .forEach(i -> parallelStorage.add(i));
        System.out.println("开始打印普通集合parallelStorage");
        parallelStorage
                .stream()
                .forEachOrdered(e -> System.out.print(e + " "));
        System.out.println();
        System.out.print("------------------------------------");
        System.out.println();
        //通过并行流存入同步集合parallelStorage2中
        integersList
                .parallelStream()
                .filter(i -> i % 2 == 0)
                .forEach(i -> parallelStorage2.add(i));
        System.out.println("开始打印同步集合parallelStorage");
        parallelStorage2
                .stream()
                .forEachOrdered(e -> System.out.print(e + " "));
    }
}

运行结果如下图

 问题与分析

1.为什么parallelStorage的数量不固定(正确的应该是50)
2.
为什么parallelStorage会有null元素?

其实我们可以认为ArrayList内部维护了一个数组Arr其定义一个变量 n用以表式这个数组的大小那么向这个ArrayList中存储数据的过程可以分解为这么几步:

1.读取数组的长度存入n
2.
向这个数组中储入元素arr[n]=a
3.
n+1
4.
保存n
而对于parrallelStorage元素数量不固定的原因就是多线程有可能同时读取到相同的下标n同时赋值,这样就会出现元素缺失的问题了

项目实战

根据时间段拉取美团订单时,我们先间隔20分钟去分割时间,然后通过一个同步集合去存储并行流中查询回来的美团订单。

 好文

Collections.synchronizedList()方法实例

希望本文章对您有帮助,您的转发、点赞是我的创作动力,十分感谢。

扫描下方二维码关注我,您会收到更多优质文章推送。

 

posted @ 2020-12-27 17:24  JustJavaIt  阅读(8274)  评论(0编辑  收藏  举报