1. 程式人生 > >11.ForkJoinPool 分支/合並框架 (工作竊取)

11.ForkJoinPool 分支/合並框架 (工作竊取)

隊列 img com images blog err forkjoin 情況 這樣的

/*ForkJoinPool 分支/合並框架 (工作竊取)*/

Fork/Join 框架:就是在必要的情況下,將一個大任務,進行拆分(fork) 成若幹個小任務(拆到給出的臨界值為止),再將一個個的小任務運算的結果 進行join匯總


Fork/Join 框架 與 線程池的區別

  1.采用 “工作竊取” 模式 (work-stealing)

當執行新的任務時它可以將其拆分成 更小的任務執行,並將小任務加到線程隊列中,當沒有任務執行時,再從一個隨機線程的隊列中偷一個並把它放在自己的隊列中


  2.相對於一般的線程池實現 ,fork/join 框架的優勢體現在對其中包含的任務的處理方式上,在一般的線程池中,如果一個線程正在執行的任務由於某些原因無法繼續運行

那麽該線程會處於等待狀態。而在fork/join 框架實現中,如果某個子問題由於等待另外一個子問題的完成而無法繼續運行。

那麽處理該子問題的線程會主動尋找其他尚未運行的子問題(竊取過來)來執行,這種方式減少了線程的等待時間,提高了性能

技術分享

 1 public class TestForkJoinPool {
 2 
 3     public static void main(String[] args) {
 4         ForkJoinPool pool = new ForkJoinPool();
 5         //計算  0L,100000000L 的總和,100000000 減去 0 大於 我們給定的臨界值 10000,所以會進行拆分,
6 //拆分成 0 50000000 ; 500000001 100000000 兩部分, 50000000 減去 0 又大於我們的臨界值,又會繼續進行拆分,直到不大於我們給定的臨界值, 7 //這樣的話,就拆分成了很多的小任務,每個線程都分配了一些小任務構成自己的任務隊列,當有些線程執行完了自己的任務時,不會直接結束線程, 8 //而是從其他線程的任務隊列中 偷取一個任務 放到自己的任務隊列中 9 //如果有線程阻塞了,也不會因為這個線程的阻塞,導致為這個線程分配的任務被阻塞無法執行,其他線程執行完了,會來幫助他的 10 ForkJoinTask<Long> task = new
ForkJoinSumCalculate(0L,100000000L); 11 12 long sum = pool.invoke(task); 13 14 System.out.println(sum); 15 } 16 } 17 18 class ForkJoinSumCalculate extends RecursiveTask<Long> { 19 /** 20 * 21 */ 22 private static final long serialVersionUID = 6145975974734867182L; 23 private long start; 24 private long end; 25 26 private static final long THURSHOLD = 10000L; //臨界值 27 28 public ForkJoinSumCalculate(long start,long end) { 29 this.start = start; 30 this.end = end; 31 } 32 33 34 35 @Override 36 protected Long compute() { 37 long length = end - start; 38 if(length <= THURSHOLD) { 39 long sum = 0L; 40 for(long i = start;i <= end;i++) { 41 sum+=i ; 42 } 43 return sum; 44 } else { 45 long middle = (start + end) / 2; 46 //又會再一次執行 compute(),但是傳入的 參數是拆分之後的 47 ForkJoinSumCalculate left = new ForkJoinSumCalculate(start, middle ); 48 left.fork(); //進行拆分,同時壓入線程隊列 49 50 //又會再一次執行 compute(),但是傳入的 參數是拆分之後的 51 ForkJoinSumCalculate right = new ForkJoinSumCalculate(middle + 1, end ); 52 right.fork(); // 53 54 return left.join() + right.join(); //結果合並 55 } 56 57 } 58 59 }

11.ForkJoinPool 分支/合並框架 (工作竊取)