日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java7之线程池ForkJoinPool

發布時間:2025/3/21 java 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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代表沒有返回值.

package com.demo; import java.util.concurrent.RecursiveAction; /** * * 繼承RecursiveAction來實現可分解的任務 * 注意無返回值 * * **/ public class PrintTask extends RecursiveAction { //每個小任務,最多只打印50個數 private static final int threshold=50; //打印任務的開始 private int start; //打印任務的結束 private int end; public PrintTask() { // TODO Auto-generated constructor stub } //打印從start到end之間的任務 public PrintTask(int start, int end) { super(); this.start = start; this.end = end; } @Override protected void compute() { if(end-start<threshold){ for(int i=start;i<end;i++){ System.out.println(Thread.currentThread().getName()+"i的值:"+i); } }else{ //當end與start之間的差大于threshold,及打印的數超過50個時, //將大任務分解成2個小任務 int middle=(start+end)/2; PrintTask left=new PrintTask(start, middle); PrintTask right=new PrintTask(middle, end); //并行執行兩個小任務 left.fork(); right.fork(); } } }

有返回值的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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。