摘要:串行流比較簡單,對于parallelStream,站在它背後的是ForkJoin架構。
本文分享自華為雲社群《深入了解Stream之foreach源碼解析》,作者:李哥技術 。
前言
Stream中的操作可以分為兩大類:中間操作與結束操作。
今天要說的foreach是屬于結束操作。
Stream流操作從并發上來分類,又可以分為并行流和串行流,今天就來刨根問底的看看吧。
foreach串行流

foreach并行流
從目前來看,parallelStream(并行流)與stream(串行流)的差別僅僅是一個變量而已。别着急,讓我們繼續往下看。
記住這裡的ordered是false,因為是并行流,不可能是有序周遊。continue。
我們來簡單分析一下ForEachTask類,它繼承于CountedCompleter。
static final class ForEachTask<S, T> extends CountedCompleter<Void> {
}
最後這裡使用ForkJoin架構,利用分治法的思想,将一個大任務拆分很多個小任務去執行,最後一一彙總到大任務。
我們一路過五關斬六将,終于将它給挖穿了。不容易啊。
總結
我們簡單回顧總結一下:
對于串行流:
1. 先得到ReferencePipeline.Head的Stream實作類,内部有一個拆分器,值是一個ArrayListSpliterator對象;
2. 對于并行流,目前線程直接調用ArrayListSpliterator對象的forEachRemaining方法。
對于并行流:
1. 先得到ReferencePipeline.Head的Stream實作類,内部有一個拆分器,值是一個ArrayListSpliterator對象;
2. 疊代的時候調用父類的forEach方法;
3. 建構一個ForEachTask,目前線程繼續執行invoke方法;
4. 最終執行java.util.stream.ForEachOps.ForEachTask#compute方法,使用ForkJoin架構,利用commomPool、ForkJoin架構分治法的思想,使用拆分器将任務拆分成不同子任務執行;
5. 對于每一個子任務都會拆分到不能再拆分為止,然後調用java.util.stream.AbstractPipeline#copyInto方法,在内部會調用不可再拆分的拆分器的forEachRemaining方法,最終調用回調使用者方法action.accept(e);
串行流比較簡單,對于parallelStream,站在它背後的男人是ForkJoin架構。