Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Java Concurrency Fork Join Pool

DZone's Guide to

Java Concurrency Fork Join Pool

How the ForkJoinPool function in Java is more useful than the executor framework due to it's recursive nature.

· Java Zone
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

The 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.

Image title

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:

Image title

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

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:
concurrency ,fork and join ,java

Published at DZone with permission of Shamik Mitra, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}