JAVA8之Stream並行的基礎ForkJoin
阿新 • • 發佈:2019-01-29
java8,首先我們來講講ForkJoin的原理,相信很多人都瞭解這個FrokJoin簡單來說就是分而治之的思想,把一個人任務分割成很多小的部分,各個小部分,獨立執行,執行在彙總到一塊,
我們看示意圖,也就是說吧各個數都拆分開來計算,然後彙總:
FrokJoinTool這個類繼承了
ExecutorService
這個類,也就是說跟執行緒池有點關係,我們在這裡學習它的3個API
說一下小需求:要把一組陣列對他進行相加:
private static int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
不廢話上程式碼:
public class AccumulatorRecursiveTask extendsRecursiveTask<Integer> {//繼承了RecusiveTask private final int start;//開始 private final int end;//結束 private final int[] data;//傳入的值 private final int LIMIT = 3;//把傳入的值分每三個執行 //無參構造嘍 public AccumulatorRecursiveTask(int start, int end, int[] data) { this.start = start; this.end = end; this.data = data; } //實現介面方法 @Override protected Integer compute() { if ((end - start) <= LIMIT) {//判斷如果結束的進去開始的小於規定數的話相加 int result = 0; for (int i = start; i < end; i++) { result += data[i]; } return result;} //ForkJoin的過程 int mid = (start + end) / 2; AccumulatorRecursiveTask left = new AccumulatorRecursiveTask(start, mid, data);//這裡的意思是分成兩個任務 AccumulatorRecursiveTask right = new AccumulatorRecursiveTask(mid, end, data); left.fork(); Integer rightResult = right.compute(); Integer leftResult = left.join(); //計算出結果 return rightResult + leftResult; } }
測試:
AccumulatorRecursiveTask task = new AccumulatorRecursiveTask(0, data.length, data); ForkJoinPool forkJoinPool = new ForkJoinPool(); Integer result = forkJoinPool.invoke(task); System.out.println("AccumulatorRecursiveTask >>" + result);總結:在資料量大的情況下Forkjoin這種多Cup執行的方式肯定比單CUp執行要快很多
其實stream的很多底層都是拿這種ForkJoin來做的所有的stream的底層都封裝了這樣的方式,而這樣的方式就是Spliterator\
關於Spilter
其實前面說的就是為了介紹這個Spliterator的它是java8裡面新加的一個新的介面,就是為了支援Stream的並行工作的
支援stream的切片程式設計的方式