Java7:Fork-Join架構__java

來源:互聯網
上載者:User
Fork-Join架構(Java 7)
       Java在JDK7之後加入了並行計算的架構Fork/Join,Fork/Join採用的是分治法,Fork 是將一個大任務拆分成若干個子任務,子任務分別去計算,而 Join 是擷取到子任務的計算結果,然後合并,這個是遞迴的過程。子任務被分配到不同的核上執行時,Fork-Join架構很適合使用於解決運行在多核心處理器上的並發問題;

總的來說Fork-Join模式的核心是分治,Fork分解任務,Join收集資料;  
  Fork/Join架構的核心類
Fork-Join架構有幾個主要的核心類:
ForkJoinPool類:線程池類,負責運行子任務,繼承自ExecutorService,可按照Java5的ExecutorServic的方式去調用它; ForkJoinPool 常用構造器:
 ForkJoinPool(int parallelism); //建立一個parallelism個並行線程的ForkJoinPool ForkJoinPool(); // 以Runtime.avaliableProcessors()方法的傳回值作為並行線程數量參數 ForkJoinPool提交線程的主要方法: submit,execute,invoke; 
  用戶端PorkJoinPool線程池提交任務 ForkJoinTask任務類內部調用任務
非同步執行 execute(ForkJoinTask) ForkJoinTask.fork
等待擷取結果 invoke(ForkJoinTask) ForkJoinTask.invoke
執行,擷取Future

submit(ForkJoinTask)

ForkJoinTask.fork(ForkJoinTask are Futures)

ForkJoinTask類:任務類的預設實現,實際一般使用的它的兩個預設實現: RecurisiveAction :沒有傳回值的任務類抽象類別。 RecurisiveTask :帶有傳回值的任務類抽象類別。 ForkJoinTask的兩個主要方法 fork 提交子任務,join 擷取子任務執行結果




※Fork-Join 架構任務的執行由ForkJoinTask類的對象之外,還可以使用一般的Callable和Runnable介面來表示任務。

異常處理
ForkJoinTask在執行的時候可能會拋出異常,但是沒辦法在主線程裡直接捕獲異常,所以ForkJoinTask提供了 i sCompletedAbnormally() 方法來檢查任務是否已經拋出異常或已經被取消了,並且可以通過ForkJoinTask的   getException  方法擷取異常。使用如下代碼:
 if(task.isCompletedAbnormally()) { System.out.println(task.getException()); } getException方法返回Throwable對象,如果任務被取消了則返回CancellationException。如果任務沒有完成或者沒有拋出異常則返回null。 


程式碼範例

樣本1: RecursiveTask 有傳回值任務類 簡要類比 Java 8 parallelStream並行資料流的sum方法(為了便於理解使用二分法實現分割,JDK中使用的是更加複雜的分割演算法); 使用 RecursiveTask 分治有傳回值的線程任務:並行計算List的sum值,在將其分割到小於閥值後再由子線程進行計算; 
 //子任務類 public static class SumTask extends RecursiveTask<Long> { private static final int THRESHOLD = 100; //規定分割閥值 private List<Long>list; private long low; private long high; public SumTask(List<Long> list,long low,long high){ this.list = list; this.low = low; this.high = high; } @Override //覆蓋compute介面,規定分治策略(採用二分法) protected Long compute() { long sum = 0; if(high - low +1 <= THRESHOLD){ sum = list.stream().skip(low).limit(high-low+1).mapToLong(x->x).sum(); //流長度小於閾值直接計算sum }else{ //流長度大於閾值,對流進行分治 long mid = (low + high) /2;  SumTask leftSubTask = new SumTask(list,low,mid); SumTask rightSubTask = new SumTask(list,mid+1,high); //分發運行子線程  leftSubTask.fork(); rightSubTask.fork();  //或者使用 invoke(lefSubTask,rightSubTask);代替以上任務提交的兩行; //擷取子線程結果

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.