Example of RecursiveAction in Java

By Arvind Rai, December 23, 2013
java.util.concurrent.RecursiveAction has been introduced in JDK 7 and is the part of fork join framework in Java. RecursiveAction extends java.util.concurrent.ForkJoinTask. The important method of RecursiveAction is compute(). RecursiveAction works recursively. It works differently in comparison to old recursive call in our program. Multiple threads work to compute a task parallelly in recursive action. On the basis of some condition we divide the task and submitted to perform computation. RecursiveAction works with fork and join which is provided by java.util.concurrent.ForkJoinTask . RecursiveAction is invoked by ForkJoinPool.

ForkJoinPool in Java

java.util.concurrent.ForkJoinPool has also been introduced in JDK 7. ForkJoinPool works like ExecutorService. ForkJoinPool invokes the ForkJoinTask . RecursiveAction is a ForkJoinTask. To invoke the task, ForkJoinPool has the method ForkJoinPool.invoke() which accepts ForkJoinTask as an argument.

ForkJoinTask.fork()

fork() method can only be invoked from within a ForkJoinPool. It executes a task asynchronously. As RecursiveAction is the sub class of ForkJoinTask, so RecursiveAction calls the fork() to run the task parallelly with another task.

ForkJoinTask.join()

join() method waits for the task completion which has been started by fork(). join() will be invoked by ForkJoinTask from and within ForkJoinPool. RecursiveAction invokes it to wait the completion of computation of all parallelly running task by fork().

Divide and Conquer Concept in RecursiveAction

RecursiveAction is recursive action by its name. For a given task, we make a plan to divide it in small task and then all those small tasks are started simultaneously by different threads provided by ForkJoinPool. Finally we get the result and conquer. We will understand it clearly in the example.

How to Use RecursiveAction in Java

Now this is the time to see the example of RecursiveAction. What we are trying to achieve in the example is we have an array of integers. I want the sum of square of the elements of array.
RecursiveActionDemo.java
package com.concretepage.util.concurrent;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class RecursiveActionDemo {
	public static void main(String[] args) {
		ForkJoinPool pool = new ForkJoinPool();
		int [] data = {1,2,3,4,5,6,7,8,9,10};
		Square app = new Square(data, 0, data.length);
		pool.invoke(app);
		System.out.println(app.result);
	}
}	
class Square extends RecursiveAction {
	   final int LIMIT = 3;
	   //keep static
	   static int result;
	   int start, end;
	   int[] data;
	   Square(int[] data, int start, int end) {
		   this.start = start;
		   this.end = end;
		   this.data = data;
	   }
	   @Override
	   protected void compute() {
		   if((end - start)< LIMIT){
			   for(int i= start;i<end;i++){
				   result+= data[i]*data[i];   
			   }
		   }else {
			 int mid = (start + end)/2;
			 Square left = new Square(data, start, mid); 
			 Square right = new Square(data, mid, end);
			 left.fork();
			 right.fork();
			 left.join();
			 right.join();
		   }
	   }
	 }
 
Here in the example, look at the divide and conquer concept. In the example we have class Square. Square is extending RecursiveAction. RecursiveAction has the compute() method that is automatically called when RecursiveAction object is invoked by ForkJoinPool. compute() method is also called when ForkJoinTask.fork() is invoked. We have been provided with an array of integers. We have divided the array on the basis of a limit value. We find the midpoint and in context to mid point we have left and right elements of array. Both left and right task parallelly started by fork() method. Now calling by join() we ensure that computation has been finished. If task has not been finished join waits for the task completion.

Output

385
POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us