zoukankan      html  css  js  c++  java
  • 关于java8新特性:stream的使用的巨大疑问

    主要还是关注一下今天遇到的情况吧。

    关于这个并行(实际上不是并行是并发才对)流。

    我想康康这个流函数并发之后会不会变快

    然后写了如下的简单代码:

    public class StremStudy {
        public static List<Integer> list1 = new ArrayList<>();
        public static List<Integer> list2 = new ArrayList<>();
        public static List<Integer> list3 = new ArrayList<>();
        public static List<Integer> list4 = new ArrayList<>();
    
        public static void main(String[] args) {
            long start1 = System.currentTimeMillis();
            IntStream.range(0,10000000).parallel().forEach(list1::add);
            System.out.println("list1时间:"+(System.currentTimeMillis()-start1)+"
    ");
            System.out.println("list1:"+list1.size()+"
    ");
    
            long start2 = System.currentTimeMillis();
            IntStream.range(0,10000000).forEach(list2::add);
            System.out.println("list2时间:"+(System.currentTimeMillis()-start2)+"
    ");
            System.out.println("list2:"+list2.size()+"
    ");
    
            long start3 = System.currentTimeMillis();
            IntStream.range(0,10000000).parallel().forEach(i->{
                synchronized (list3){
                    list3.add(i);
                }
            });
            System.out.println("list3时间:"+(System.currentTimeMillis()-start3)+"
    ");
            System.out.println("list3:"+list3.size()+"
    ");
    
            long start4 = System.currentTimeMillis();
            IntStream.range(0,10000000).parallel().forEach(list4::add);
            System.out.println("list4时间:"+(System.currentTimeMillis()-start4)+"
    ");
            System.out.println("list4:"+list4.size()+"
    ");
    
        }
    }

    检查并行流,普通流,加锁并行流的执行结果与执行时间。

    发现往常都是这样的三种情况

    要么结果类似下面的:并行流执行久,串行流快。(数据量少时)

    ps:list1是用来牺牲的,直接不在意就好。它主要还是为了基础的线程创建。

    list1时间:115
    
    list1:66508
    
    list2时间:6
    
    list2:100000
    
    list3时间:14
    
    list3:100000

    list4时间:11
    list4:74546
    
    Process finished with exit code 0

    要么是这样(数据量大时):【给的数据太大,第一次直接gc了。惊呆了】

    后来调小了一点。然后拿到了类似下面的结果。

    然后就能明显看到结果了。并行流确实快。

    list1时间:1209

    list1:4781548

    list2时间:2936

    list2:10000000

    list3时间:3816

    list3:10000000

    list4时间:510

    list4:3282445

    然后就是第三种情况,直接报错:告诉我流式运算那一行有问题

    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 823
        at java.util.ArrayList.add(ArrayList.java:459)
        at java.util.stream.ForEachOps$ForEachOp$OfInt.accept(ForEachOps.java:205)
        at java.util.stream.Streams$RangeIntSpliterator.forEachRemaining(Streams.java:110)
        at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
        at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
        at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:401)
        at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:734)
        at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
        at java.util.stream.ForEachOps$ForEachOp$OfInt.evaluateParallel(ForEachOps.java:189)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
        at java.util.stream.IntPipeline.forEach(IntPipeline.java:404)
        at java.util.stream.IntPipeline$Head.forEach(IntPipeline.java:560)
        at rushTime.StremStudy.main(StremStudy.java:14)

    然后我们拿到结论

    parallelStream是线程不安全的并发流式运算。

    谨慎使用吧。

  • 相关阅读:
    使用.sig签名验证文件
    ubuntu server 安装nextcloud12
    centos 搭建owncloud私有云
    archlinux错误:无法提交处理 (无效或已损坏的软件包)
    Oracle数据库-建库、建表空间,建用户
    JS中几种遍历方式
    常用的正则表达式
    JavaWeb中GET请求url传参中文乱码问题
    常用的ajax方式
    table中td内容过长自动换行
  • 原文地址:https://www.cnblogs.com/hekiraku/p/12023799.html
Copyright © 2011-2022 走看看