如何進行JDK7新特性中fork/join框架的原理分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
原理解析:fork分解,join結合。這個框架的本質是將一個任務分解成多個子任務,每個子任務用單獨的線程去處理。這里用到了遞歸的思想??蚣艿慕Y構圖可以參考
使用fork/join 框架很簡單,
1.實現子問題的一般求解算法
2.如何分解問題
3.繼承 RecursiveAction ,實現compute()方法
偽代碼代碼
Result solve(Problem problem) { if (problem is small) directly solve problem else { split problem into independent parts fork new subtasks to solve each part join all subtasks compose result from subresults }
這里我通過一個改進的二分查找來講解fork/join的使用。(后面才發現,選用這個案例是非常失敗的,因為二分查找的時間是logn,而創建線程的開銷更大,這樣并不能體現多線程二分查找的優勢,所以這個代碼不具有實用性,只是為了說明如何使用框架:)
代碼如下:
BinarySearchProblem.java
Java代碼
package testjdk7; import java.util.Arrays; /** * @author kencs@foxmail.com */ public class BinarySearchProblem { private final int[] numbers; private final int start; private final int end; public final int size; public BinarySearchProblem(int[] numbers,int start,int end){ this.numbers = numbers; this.start = start; this.end = end; this.size = end -start; } public int searchSequentially(int numberToSearch){ //偷懶,不自己寫二分查找了 return Arrays.binarySearch(numbers, start, end, numberToSearch); } public BinarySearchProblem subProblem(int subStart,int subEnd){ return new BinarySearchProblem(numbers,start+subStart,start+subEnd); } }
BiSearchWithForkJoin.java
Java代碼
package testjdk7; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveAction; /** * @author kencs@foxmail.com */ public class BiSearchWithForkJoin extends RecursiveAction { private final int threshold; private final BinarySearchProblem problem; public int result; private final int numberToSearch; public BiSearchWithForkJoin(BinarySearchProblem problem,int threshold,int numberToSearch){ this.problem = problem; this.threshold = threshold; this.numberToSearch = numberToSearch; } @Override protected void compute() { if(problem.size < threshold){ //小于閥值,就直接用普通的二分查找 result = problem.searchSequentially(numberToSearch); }else{ //分解子任務 int midPoint = problem.size/2; BiSearchWithForkJoin left = new BiSearchWithForkJoin(problem.subProblem(0, midPoint),threshold,numberToSearch); BiSearchWithForkJoin right = new BiSearchWithForkJoin(problem.subProblem(midPoint+1, problem.size),threshold,numberToSearch); invokeAll(left,right); result = Math.max(left.result, right.result); } } //構造數據 private static final int[] data = new int[1000_0000]; static{ for(int i = 0;i<1000_0000;i++){ data[i] = i; } } public static void main(String[] args){ BinarySearchProblem problem = new BinarySearchProblem(data,0,data.length); int threshold = 100; int nThreads = 10; //查找100_0000所在的下標 BiSearchWithForkJoin bswfj = new BiSearchWithForkJoin(problem,threshold,100_0000); ForkJoinPool fjPool = new ForkJoinPool(nThreads); fjPool.invoke(bswfj); System.out.printf("Result is:%d%n",bswfj.result); } }
RecursiveTask 還可以帶返回值,這里給出一段代碼作為參考(斐波那契函數)
(來自http://www.ibm.com/developerworks/cn/java/j-lo-forkjoin/index.html)
Java代碼
class Fibonacci extends RecursiveTask { final int n; Fibonacci(int n) { this.n = n; } private int compute(int small) { final int[] results = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 }; return results[small]; } public Integer compute() { if (n <= 10) { return compute(n); } Fibonacci f1 = new Fibonacci(n - 1); Fibonacci f2 = new Fibonacci(n - 2); System.out.println("fork new thread for " + (n - 1)); f1.fork(); System.out.println("fork new thread for " + (n - 2)); f2.fork(); return f1.join() + f2.join(); } }
用途
只要問題能夠分解成類似子問題的,都可以使用這個框架。對于大批量的數據尤其合適。
看完上述內容,你們掌握如何進行JDK7新特性中fork/join框架的原理分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。