摘要:串行流比較簡單,對于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框架,
ForkJoin框架是從jdk7中新特性,它同ThreadPoolExecutor一樣,也實作了Executor和ExecutorService介面,ForkJoinPool主要用來使用分治法(Divide-and-Conquer Algorithm)來解決問題,Java 8為ForkJoinPool添加了一個通用執行緒池:commonPool,這個執行緒池用來處理那些沒有被顯式提交到任何執行緒池的任務,它是ForkJoinPool型別上的一個靜態元素,它擁有的默認執行緒數量等于運行計算機上的處理器數量,所以,我們的并行流就是使用的這個公共池中的執行緒來執行的,
點擊關注,第一時間了解華為云新鮮技術~
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/508775.html
標籤:其他
