掌握Fork/Join 框架,证明你Java毕业了( 二 )

4. Fork/Join 框架实例
在本节中,我们将通过几个实际示例来展示如何使用 Fork/Join 框架解决问题 。
4.1 计算斐波那契数列
以下示例演示了如何使用 Fork/Join 框架计算斐波那契数列的第 n 项:
import java.util.concurrent.ForkJoinPool;import java.util.concurrent.RecursiveTask;public class FibonacciTask extends RecursiveTask {private final int n;public FibonacciTask(int n) {this.n = n;@Overrideprotected Integer compute() {if (n <= 1) {return n;FibonacciTask task1 = new FibonacciTask(n - 1);task1.fork();FibonacciTask task2 = new FibonacciTask(n - 2);return task2.compute() + task1.join();public static void main(String[] args) {ForkJoinPool pool = new ForkJoinPool();int n = 10;FibonacciTask task = new FibonacciTask(n);int result = pool.invoke(task);System.out.println("The " + n + "th Fibonacci number is: " + result);4.2 归并排序
以下示例演示了如何使用 Fork/Join 框架实现归并排序算法:
import java.util.Arrays;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.RecursiveAction;public class MergeSortTask extends RecursiveAction {private final int[] array;private final int low;private final int high;public MergeSortTask(int[] array, int low, int high) {this.array = array;this.low = low;this.high = high;@Overrideprotected void compute() {if (high - low <= 1) {return;int mid = (low + high) >>> 1;MergeSortTask leftTask = new MergeSortTask(array, low, mid);MergeSortTask rightTask = new MergeSortTask(array, mid, high);invokeAll(leftTask, rightTask);merge(array, low, mid, high);private void merge(int[] array, int low, int mid, int high) {int[] temp = Arrays.copyOfRange(array, low, mid);int i = low, j = mid, k = 0;while (i < j && j < high) {if (array[j] < temp[k]) {array[i++] = array[j++];} else {array[i++] = temp[k++];while (i < j) {array[i++] = temp[k++];public static void main(String[] args) {ForkJoinPool pool = new ForkJoinPool();int[] array = {5, 3, 1, 2, 6, 4};MergeSortTask task = new MergeSortTask(array, 0, array.length);pool.invoke(task);System.out.println("Sorted array: " + Arrays.toString(array));4.3 并行矩阵相乘
在本节中,我们将使用 Fork/Join 框架实现并行矩阵相乘 。假设我们有两个矩阵 A 和 B,我们的任务是计算它们的乘积矩阵 C 。
首先,我们创建一个继承自 RecursiveTask 的类 MatrixMultiplicationTask:
public class MatrixMultiplicationTask extends RecursiveTask {private static final int THRESHOLD = 64;private final double[][] A, B;private final int rowStart, rowEnd, colStart, colEnd;public MatrixMultiplicationTask(double[][] A, double[][] B, int rowStart, int rowEnd, int colStart, int colEnd) {this.A = A;this.B = B;this.rowStart = rowStart;this.rowEnd = rowEnd;this.colStart = colStart;this.colEnd = colEnd;@Overrideprotected double[][] compute() {
在 compute() 方法中,我们将实现任务的分解和合并逻辑:
@Overrideprotected double[][] compute() {int numRows = rowEnd - rowStart;int numCols = colEnd - colStart;if (numRows <= THRESHOLD && numCols <= THRESHOLD) {return multiplyMatricesDirectly();} else {private double[][] multiplyMatricesDirectly() {int numRows = rowEnd - rowStart;int numCols = colEnd - colStart;int numCommon = A[0].length;double[][] C = new double[numRows][numCols];for (int i = 0; i < numRows; i++) {for (int j = 0; j < numCols; j++) {double sum = 0;for (int k = 0; k < numCommon; k++) {sum += A[rowStart + i][k] * B[k][colStart + j];C[i][j] = sum;return C;
如果任务足够小(小于阈值),我们将直接计算矩阵相乘的结果 。否则,我们将任务分解为四个子任务,并将这些子任务分配给其他线程 。
} else {int rowMid = (rowStart + rowEnd) / 2;int colMid = (colStart + colEnd) / 2;MatrixMultiplicationTask task11 = new MatrixMultiplicationTask(A, B, rowStart, rowMid, colStart, colMid);MatrixMultiplicationTask task12 = new MatrixMultiplicationTask(A, B, rowStart, rowMid, colMid, colEnd);MatrixMultiplicationTask task21 = new MatrixMultiplicationTask(A, B, rowMid, rowEnd, colStart, colMid);MatrixMultiplicationTask task22 = new MatrixMultiplicationTask(A, B, rowMid, rowEnd, colMid, colEnd);invokeAll(task11, task12, task21, task22);double[][] C11 = task11.join();double[][] C12 = task12.join();double[][] C21 = task21.join();double[][] C22 = task22.join();return combineMatrices(C11, C12, C21, C22);private double[][] combineMatrices(double[][] C11, double[][] C12, double[][] C21, double[][] C22) {int numRows = C11.length + C21.length;int numCols = C11[0].length + C12[0].length;double[][] C = new double[numRows][numCols];for (int i = 0; i < numRows; i++) {for (int j = 0; j < numCols; j++) {if (i < C11.length && j < C11[0].length) {C[i][j] = C11[i][j];} else if (i < C11.length) {C[i][j] = C12[i][j - C11[0].length];} else if (j < C11[0].length) {C[i][j] = C21[i - C11.length][j];} else {C[i][j] = C22[i - C11.length][j - C11[0].length];return C;


推荐阅读