Stream笔记 并行流

stream


源码:跟踪Stream并行流工作原理 

List<String> lst0 = Arrays.asList("a0are", "a1where", "a2anvato", "a3java", "b4abc", "b5123", "c6hello", "c7world", "d8!!!");

ArrayList<String> list = new ArrayList<>(lst0);

List<String> result =
      list.parallelStream()               //定义输入源,   得到Stage0 Head节点(流)
          .filter(s -> s.startsWith("a")) //定义中间操作, 得到Stage1 StatelessOp节点(流)
          .sorted()                       //定义中间操作, 得到Stage2 StatefulOp节点(流),SortedOps.OfRef实例
          .limit(3)                       //定义中间操作, 得到Stage3 StatefulOp节点(流),SliceOps的StatefulOp实例
          .map(s -> s.subString(1))       //定义中间操作, 得到Stage4 StatelessOp节点(流)
          .collect(Collectors.toList());  //定义终端操作, TerminalOp节点(流),ReduceOp实例

list.parallelStream()语句:分析

list当前是ArrayList类的一个实例,查看ArrayList类源码后,发现ArrayList类内没有parallelStream()方法;继续查看List接口,发现List接口也没有parallelStream()方法;继续查看超级Collection接口,发现内部有默认的parallelStream()方法,这是jdk1.8版本新引入的一种技术手段,接口内可以拥有默认的实现方法。

JDK8新增:接口中可提供默认方法 default修饰符。默认实现可以从本质上根除适配器模式。
JDK8新增:接口中可提供静态方法 static修饰符。可以 接口名.静态方法() 来调用。
JDK8新增:接口中可声明变量,隐式默认为public final static

  • Collection接口的parallelStream()方法
//Collection集合超级接口内的默认方法
default Stream<E> parallelStream() {
    return StreamSupport.stream(spliterator(), true); //并行流
}

spliterator()方法,当前调用parallelStream()的对象list是ArrayList类的实例,所以先看看ArrayList类中有没有spliterator方法,查看源码后,发现ArrayList类中有spliterator方法

  • ArrayList类的spliterator()方法
public Spliterator<E> spliterator() {
    return new ArrayListSpliterator<>(this, 0, -1, 0);
    //返回一个拆分迭代器,初始时为index=0起使,fence=-1围栏,修改次数0
}

//ArrayList的内部类
static final class ArrayListSpliterator<E> implements Spliterator<E> {        

        private final ArrayList<E> list;
        private int index; // current index, modified on advance/split
        private int fence; // -1 until used; then one past last index
        private int expectedModCount; // initialized when fence set

        /** Create new spliterator covering the given  range */
        ArrayListSpliterator(ArrayList<E> list, int origin, int fence, int expectedModCount) {
            this.list = list; // OK if null unless traversed
            this.index = origin;
            this.fence = fence;
            this.expectedModCount = expectedModCount;
        }

        public int characteristics() {//特性值集:有序且知晓大小的
            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
        }
}

拿到了一个拆分器ArrayListSpliterator(list,0,-1,0)后,接着看语句StreamSupport.stream(spliterator(), true);

  • StreamSupport.stream(spliterator,true)方法
public static <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel) {

    return new ReferencePipeline.Head<>(
                    spliterator, //上方拿到的ArrayListSpliterator(list,0,-1,0);
                    StreamOpFlag.fromCharacteristics(spliterator),
                    parallel);
}

//StreamOpFlag类的静态方法
static int fromCharacteristics(Spliterator<?> spliterator) {
        int characteristics = spliterator.characteristics();
        if ((characteristics & Spliterator.SORTED) != 0 && spliterator.getComparator() != null) {
            // Do not propagate the SORTED characteristic if it does not correspond
            // to a natural sort order
            return characteristics & SPLITERATOR_CHARACTERISTICS_MASK & ~Spliterator.SORTED;
        }
        else {
            return characteristics & SPLITERATOR_CHARACTERISTICS_MASK; //拆分器特性值的掩码
        }
}

//ReferencePipeline类的内部类(ReferencePipeline实现了stream部分接口,继承AbstractPipeline类)
static class Head<E_IN, E_OUT> extends ReferencePipeline<E_IN, E_OUT> {
        //Head节点的构造函数,Head是个流,代表Stage0
        Head(Spliterator<?> source, int sourceFlags, boolean parallel) {
            super(source, sourceFlags, parallel);
        }
}

//Head节点最终调用的构造函数在AbstractPipeline中(Stage0~StageN的构造函数都在AbstractPipeline类中)
AbstractPipeline(Spliterator<?> source, int sourceFlags, boolean parallel) {
        this.previousStage = null; //Head节点无前序节点
        this.sourceSpliterator = source; //上方拿到的ArrayListSpliterator(list,0,-1,0);
        this.sourceStage = this;
        this.sourceOrOpFlags = sourceFlags & StreamOpFlag.STREAM_MASK;
        this.combinedFlags = (~(sourceOrOpFlags << 1)) & StreamOpFlag.INITIAL_OPS_VALUE;
        this.depth = 0;           //Head节点深度0
        this.parallel = parallel; //Head节点流是并行流
    }

list.parallelStream()语句:结果:拿到Head节点并行流,Stage0节点建立完毕

现在我们拿到这句话的执行结果,得到了一个Head节点流,也即Stage0阶段,该Head节点流是个并行流,深度0。为了简化理解,我们现在不谈及掩码(也就是MASK或者说Flags)的问题,掩码的存在是为了提高优化并行的运算而设计的,并不会影响我们写的主体业务逻辑代码,优化机制是JVM内部做的,当然,我们很清楚掩码的作用,那么就能写出来更高质量的代码,关于掩码的讲解,在另外一节来专门讲解。现在,我们就假定没搞掩码,自然无法通知JVM做一些优化策略,就全当JVM累点,土了一点,别优化给我好好的执行代码就行。


Stage0.filter(s -> s.startsWith("a")) 语句:分析

//调用filter方法时,是Head节点也即Stage0阶段 调用的,所以filter的入参this是Head节点对象
    public final Stream<P_OUT> filter(Predicate<? super P_OUT> predicate) {
     
        return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE, StreamOpFlag.NOT_SIZED) {
                Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {                
                    //这里的方法体内容我先注释,后面在看,因为现在创建Stage阶段,还用不到opWrapSink方法
                }
        };
    }
     
    //StatelessOp类的构造函数
    StatelessOp(AbstractPipeline<?, E_IN, ?> upstream, StreamShape inputShape, int opFlags) {
        super(upstream, opFlags){
        upstream.linkedOrConsumed = true;
     
        upstream.nextStage = this;         //Stage0的下一阶段是Stage1 双向链表的建立
        this.upstream = upstream;          //Stage1的前一阶段是Stage0 双向链表的建立
     
        this.depth = upstream.depth + 1;   //Stage1的深度是1
     
        this.sourceStage = upstream.sourceStage;
        this.sourceOrOpFlags = opFlags & StreamOpFlag.OP_MASK;
        this.combinedFlags = StreamOpFlag.combineOpFlags(opFlags, upstream.combinedFlags);                
        }
    }
     
    /**
    * filter方法调用后,我们得到了Stage1阶段,并且建立好了双向链表
    */

Stage0.filter()语句:结果:我们拿到了中间操作filter的节点,也即Stage1阶段已经建立完毕,并建立好双向链表


Stage1.sorted()语句:分析

    public final Stream<P_OUT> sorted() {
        return SortedOps.makeRef(this); //这个this是当前的Stage1
    }
     
    //SortedOps类的静态方法makeRef
    static <T> Stream<T> makeRef(AbstractPipeline<?, T, ?> upstream) {
        return new OfRef<>(upstream);
    }
     
    //SortedOps的内部类OfRef
    private static final class OfRef<T> extends ReferencePipeline.StatefulOp<T, T> {
        OfRef(AbstractPipeline<?, T, ?> upstream) {
            super(upstream, StreamShape.REFERENCE, StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
                this.isNaturalSort = true;
                Comparator<? super T> comp = (Comparator<? super T>) Comparator.naturalOrder();
                this.comparator = comp;
        }
     
        public Sink<T> opWrapSink(int flags, Sink<T> sink){
            //这里先注释掉,创建Stage2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值