Java Concurrency Fork Join Pool
How the ForkJoinPool function in Java is more useful than the executor framework due to it's recursive nature.
Join the DZone community and get the full member experience.
Join For FreeThe ForkJoinPool was introduced in Java 7. Is is similar to the Executor framework but with one difference. ForkjoinPools act in a recursive way, unlike Executor threads, which splits the task and submits smaller chunks to worker Threads. ForkJoinPool takes a big task, splits it into smaller tasks, and those smaller tasks split themselves again into subtasks until each subtask is atomic or not divisible. So it works recursively.
Please see the following picture , know the ForkJoin pool concept.
Divide bigger Task into smaller tasks in a recursive way
Fork: Split larger task into smaller tasks. Ex: Task 1.1 splits to Task 1.1.1 and Task 1.1.2
Join: Get result from immediate subtasks. Ex: Task 1.1 take results from Task 1.1.1 and Task 1.1.2
Fork-Join pool is faster than Executor service:
For example, suppose we want to search an element in a sorted array. So obviously we take the help of a Binary Search algorithm.
- Step 1: First we split the array and determine the mid element of the array .
- Step 2: Check searchable element is equal to mid element. If it is equal, then return the element ,as it is found in the array.
- Step 3: If the element is less than mid element then we create a new subtask, in this sub-task, we take left half of the array.
- Step 4: If the element is greater than mid element then we create a new subtask ,in this sub-task ,we take right half of the array.
- Step 5: Until element is not found continue the step 4 and 5.
- Step 6: If the array size is 1 and elements are not equal to that element. Return status as Not Found.
Code
package com.example.concurrency;
import java.util.Arrays;
import java.util.concurrent.RecursiveTask;
publicclassForkJoinSearcherextends RecursiveTask<Boolean>{
int[] arr;
int searchableElement;
ForkJoinSearcher(int[] arr,int search)
{
this.arr = arr;
this.searchableElement=search;
}
@Override
protected Boolean compute() {
int mid=( 0 + arr.length)/2;
System.out.println(Thread.currentThread().getName() + " says : After splliting the arry length is :: "+ arr.length + " Midpoint is " + mid);
if(arr[mid]=searchableElement)
{
System.out.println(" FOUND !!!!!!!!!");
return true;
}
elseif(mid=1 || mid == arr.length)
{
System.out.println("NOT FOUND !!!!!!!!!");
returnfalse;
}
elseif(searchableElement < arr[mid])
{
System.out.println(Thread.currentThread().getName() + " says :: Doing Left-search");
int[] left = Arrays.copyOfRange(arr, 0, mid);
ForkJoinSearcher forkTask = new ForkJoinSearcher(left,searchableElement);
forkTask.fork();
return forkTask.join();
}
elseif(searchableElement > arr[mid])
{
System.out.println(Thread.currentThread().getName() + " says :: Doing Right-search");
int[] right = Arrays.copyOfRange(arr, mid, arr.length);
ForkJoinSearcher forkTask = new ForkJoinSearcher(right,searchableElement);
forkTask.fork();
return forkTask.join();
}
returnfalse;
}
}
package com.example.concurrency;
import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
publicclass BinarySearch {
int[] arr = newint[100];
public BinarySearch()
{
init();
}
privatevoid init()
{
for(int ; i<arr.length;i++)
{
arr[i];
}
Arrays.sort(arr);
}
publicvoid createForJoinPool(int search)
{
ForkJoinPool forkJoinPool = new ForkJoinPool(50);
ForkJoinSearcher searcher = new ForkJoinSearcher(this.arr,search);
Boolean status = forkJoinPool.invoke(searcher);
System.out.println(" Element ::" + search +" has been found in array? :: " + status );
}
publicstaticvoid main(String[] args) {
BinarySearch search = new BinarySearch();
search.createForJoinPool(10);
System.out.println("**********************");
search.createForJoinPool(104);
}
}
Output
ForkJoinPool-1-worker-57 says : After splliting the arry length is :: 100 Midpoint is 50
ForkJoinPool-1-worker-57 says :: Doing Left-search
ForkJoinPool-1-worker-57 says : After splliting the arry length is :: 50 Midpoint is 25
ForkJoinPool-1-worker-57 says :: Doing Left-search
ForkJoinPool-1-worker-50 says : After splliting the arry length is :: 25 Midpoint is 12
ForkJoinPool-1-worker-50 says :: Doing Left-search
ForkJoinPool-1-worker-57 says : After splliting the arry length is :: 12 Midpoint is 6
ForkJoinPool-1-worker-57 says :: Doing Right-search
ForkJoinPool-1-worker-50 says : After splliting the arry length is :: 6 Midpoint is 3
ForkJoinPool-1-worker-50 says :: Doing Right-search
ForkJoinPool-1-worker-43 says : After splliting the arry length is :: 3 Midpoint is 1
FOUND !!!!!!!!!
Element ::10 has been found in array? :: true
**********************
ForkJoinPool-2-worker-57 says : After splliting the arry length is :: 100 Midpoint is 50
ForkJoinPool-2-worker-57 says :: Doing Right-search
ForkJoinPool-2-worker-57 says : After splliting the arry length is :: 50 Midpoint is 25
ForkJoinPool-2-worker-57 says :: Doing Right-search
ForkJoinPool-2-worker-50 says : After splliting the arry length is :: 25 Midpoint is 12
ForkJoinPool-2-worker-50 says :: Doing Right-search
ForkJoinPool-2-worker-57 says : After splliting the arry length is :: 13 Midpoint is 6
ForkJoinPool-2-worker-57 says :: Doing Right-search
ForkJoinPool-2-worker-50 says : After splliting the arry length is :: 7 Midpoint is 3
ForkJoinPool-2-worker-50 says :: Doing Right-search
ForkJoinPool-2-worker-57 says : After splliting the arry length is :: 4 Midpoint is 2
ForkJoinPool-2-worker-57 says :: Doing Right-search
ForkJoinPool-2-worker-43 says : After splliting the arry length is :: 2 Midpoint is 1
NOT FOUND !!!!!!!!!
Element ::104 has been found in array? :: false
Published at DZone with permission of Shamik Mitra, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments