From what I read of tutorial, is a little different.
In C, when you do Fork, you have 2 processes, a father and a son. In possession of the child’s pid, the parent process can do the Join, when the child process ends.
In Java, the algorithm is similar, but the operation for the Operating System is different. The algorithm is
se (a parte de trabalho for pequena o suficiente)
faça o que tem que fazer
caso contrário
divida o meu trabalho em duas partes
execute as duas partes e espere pelo resultado
Example taken from University of Washington:
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
class Sum extends RecursiveTask<Long> {
static final int SEQUENTIAL_THRESHOLD = 5000;
int low;
int high;
int[] array;
Sum(int[] arr, int lo, int hi) {
array = arr;
low = lo;
high = hi;
}
protected Long compute() {
if(high - low <= SEQUENTIAL_THRESHOLD) {
long sum = 0;
for(int i=low; i < high; ++i)
sum += array[i];
return sum;
} else {
int mid = low + (high - low) / 2;
Sum left = new Sum(array, low, mid);
Sum right = new Sum(array, mid, high);
left.fork();
long rightAns = right.compute();
long leftAns = left.join();
return leftAns + rightAns;
}
}
static long sumArray(int[] array) {
return ForkJoinPool.commonPool().invoke(new Sum(array,0,array.length));
}
}
In this example, you sum the elements of an Array. If the array has more than 5000 elements, the task will be divided. The method compute
implements the described pseudo-code.
Ordering example:
static class SortTask extends RecursiveAction {
final long[] array; final int lo, hi;
SortTask(long[] array, int lo, int hi) {
this.array = array; this.lo = lo; this.hi = hi;
}
SortTask(long[] array) { this(array, 0, array.length); }
protected void compute() {
if (hi - lo < THRESHOLD)
sortSequentially(lo, hi);
else {
int mid = (lo + hi) >>> 1;
invokeAll(new SortTask(array, lo, mid),
new SortTask(array, mid, hi));
merge(lo, mid, hi);
}
}
// implementation details follow:
static final int THRESHOLD = 1000;
void sortSequentially(int lo, int hi) {
Arrays.sort(array, lo, hi);
}
void merge(int lo, int mid, int hi) {
long[] buf = Arrays.copyOfRange(array, lo, mid);
for (int i = 0, j = lo, k = mid; i < buf.length; j++)
array[j] = (k == hi || buf[i] < array[k]) ?
buf[i++] : array[k++];
}
}
First you have to choose the type of Task
. Are two options:
RecusiveTask
: returns a result after Fork
ActionTask
: does not return a result after Fork
Second you have to implement the Compute method by following the pseudo-algorithm, using invokeAll
, compute
, fork
and join
.
Finally, you have to use a thread pool called ForkJoinPool
. I saw at least two ways:
ForkJoinPool.commonPool().invoke(task);
or
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(task);
At the bottom of the cloths, java.util.Arrays.parallelSort uses Fork/Join API.
The whole problem is that we’re trying to implement the equivalent in Java, so Doubt.
– Paulo Magno Rodrigues Salum
If you want to ask another question about how to implement Fork in java or you can check here the documentation for java https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html. But I suggest you ask another question msm.
– gato