Java7之线程池ForkJoinPool
許多情況下,在一個程序中使用多線程是有益處的,可以大大提高程序的效率,多線程主要有以下3個優點1,資源利用率更好2,程序設計在某些情況下更簡單3,程序響應更快。當然凡事有利就有弊,多線程也會使程序的開發,維護及調試更加復雜,當然如果我們能夠揚長避短,在正確的場合下使用多線程,那么它將成為我們程序中開發的利器。
Java一直以來,對多線程的開發支持比較良好,特別在JDK5,6后引入的java.util.concurrent包,使用多線程的開發變的更加容易,這個包里面大部分的API都是更進一步的封裝,作為開發者,我們只需熟悉它怎么使用,就能夠很輕松的上手,當然如果你想完全搞懂它,那么就需要讀讀那些優秀的源碼了。
ForkJoinPool這個類是JDK7后新增的線程池,很適合在單機多核的PC上部署多線程程序,ForkJoinPool使用的分而治之的思想,這一點與當前很火的大數據處理框架Hadoop的map/reduce思想非常類似,但是他們的使用場合卻不一樣,ForkJoinPool適合在一臺PC多核CPU上運行,而hadoop則適合在分布式環境中進行大規模集群部署。
Fork/Join 模式有自己的適用范圍。如果一個應用能被分解成多個子任務,并且組合多個子任務的結果就能夠獲得最終的答案,那么這個應用就適合用 Fork/Join 模式來解決.
ForkJoinPool使用的工作竊取的方式能夠在最大方式上充分利用CPU的資源,一般流程是fork分解,join結合。本質是將一個任務分解成多個子任務,每個子任務用單獨的線程去處理,主要幾個常用方法有
關于上表中的ForkJoinTask是一個抽象類,代表一個可以fork與join的任務. ,它還有2個抽象子類:RecursiveAcion和RecursiveTask.其中RecursiveTask代表有泛型返回值的任務.而RecursiveAction代表沒有返回值.
有返回值的demo
package com.demo; import java.util.concurrent.RecursiveTask; /*** * 有返回值 * * */ public class CalTask extends RecursiveTask<Integer>{ //將每個小任務,最多只能累加20個數 private static final int threshold=20; private int arr[]; private int start;//開始 private int end;// //累加從start到end之間的數 public CalTask() { // TODO Auto-generated constructor stub } //累加從start到end的數組元素 public CalTask(int[] arr, int start, int end) { super(); this.arr = arr; this.start = start; this.end = end; } @Override protected Integer compute() { int sum=0; //當end與start之間的差小于threshold,開始進行累加 if(end-start<threshold){ for(int i=start;i<end;i++){ sum+=arr[i]; } return sum; }else{ //當end與start之間的差大于threshold,要計算的數超過20個時, //將大任務分解成兩個小任務 int middle=(start+end)/2; CalTask left=new CalTask(arr, start, middle); CalTask right=new CalTask(arr, middle, end); //并行執行2個小任務 left.fork(); right.fork(); //把2個小任務,累加的結果合并起來 return left.join()+right.join(); } } } package com.demo; import java.util.Random; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.Future; public class Sum { public static void main(String[] args)throws Exception { int []arr=new int[1100]; Random rand=new Random(); int total=0; //初始化100個數字 for(int i=0;i<arr.length;i++){ int tmp=rand.nextInt(20); //對元素賦值,并將數組元素的值添加到total總和中 total+=(arr[i]=tmp); } System.out.println("正確的total:"+total); ForkJoinPool pool=new ForkJoinPool(); //提交可分解的CalTask任務 Future<Integer> future=pool.submit(new CalTask(arr, 0, arr.length)); System.out.println(future.get()); //關閉線程池 pool.shutdown(); } }總結
以上是生活随笔為你收集整理的Java7之线程池ForkJoinPool的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: docker-compose配置redi
- 下一篇: Linux每次开机都要source /e