关于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)+"\n");
        System.out.println("list1:"+list1.size()+"\n");

        long start2 = System.currentTimeMillis();
        IntStream.range(0,10000000).forEach(list2::add);
        System.out.println("list2时间:"+(System.currentTimeMillis()-start2)+"\n");
        System.out.println("list2:"+list2.size()+"\n");

        long start3 = System.currentTimeMillis();
        IntStream.range(0,10000000).parallel().forEach(i->{
            synchronized (list3){
                list3.add(i);
            }
        });
        System.out.println("list3时间:"+(System.currentTimeMillis()-start3)+"\n");
        System.out.println("list3:"+list3.size()+"\n");

        long start4 = System.currentTimeMillis();
        IntStream.range(0,10000000).parallel().forEach(list4::add);
        System.out.println("list4时间:"+(System.currentTimeMillis()-start4)+"\n");
        System.out.println("list4:"+list4.size()+"\n");

    }
}

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

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

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

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是线程不安全的并发流式运算。

谨慎使用吧。

猜你喜欢

转载自www.cnblogs.com/hekiraku/p/12023799.html