Mega Code Archive

 
Categories / Java Book / 007 Thread Conncurrent
 

0403 ForkJoin Framework

Fork/Join consists of a special executor service and thread pool. The Fork/Join breaks a task down into smaller tasks that are forked (executed by different threads) from the pool. A task waits until joined (its subtasks finish). The following code shows how to multiply two matrixes via the Fork/Join Framework import java.util.ArrayList; import java.util.List; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveAction; public class Main{ public static void main(String[] args) { Matrix a = new Matrix(2, 3); a.setValue(0, 0, 1); // | 1 2 3 | a.setValue(0, 1, 2); // | 4 5 6 | a.setValue(0, 2, 3); a.setValue(1, 0, 4); a.setValue(1, 1, 5); a.setValue(1, 2, 6); Matrix b = new Matrix(3, 2); b.setValue(0, 0, 7); // | 7 1 | b.setValue(1, 0, 8); // | 8 2 | b.setValue(2, 0, 9); // | 9 3 | b.setValue(0, 1, 1); b.setValue(1, 1, 2); b.setValue(2, 1, 3); Matrix c = new Matrix(2, 2); ForkJoinPool pool = new ForkJoinPool(); pool.invoke(new Calc(a, b, c)); } } class Calc extends RecursiveAction { private Matrix a, b, c; private int row; Calc(Matrix a, Matrix b, Matrix c) { this(a, b, c, -1); } Calc(Matrix a, Matrix b, Matrix c, int row) { if (a.getCols() != b.getRows()) { throw new IllegalArgumentException("rows/columns mismatch"); } this.a = a; this.b = b; this.c = c; this.row = row; } @Override public void compute() { if (row == -1) { List<Calc> tasks = new ArrayList<>(); for (int row = 0; row < a.getRows(); row++) { tasks.add(new Calc(a, b, c, row)); } invokeAll(tasks); } else { multiplyRowByColumn(a, b, c, row); } } void multiplyRowByColumn(Matrix a, Matrix b, Matrix c, int row) { for (int j = 0; j < b.getCols(); j++) { for (int k = 0; k < a.getCols(); k++) { c.setValue(row, j, (int)(c.getValue(row, j) + a.getValue(row, k)* b.getValue(k, j))); } } } } class Matrix { private int[][] doubleArray; Matrix(int nrows, int ncols) { doubleArray = new int[nrows][ncols]; } int getCols() { return doubleArray[0].length; } int getRows() { return doubleArray.length; } double getValue(int row, int col) { return doubleArray[row][col]; } void setValue(int row, int col, int value) { doubleArray[row][col] = value; } }