Fork/Join 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;
}
}