1) I used here java 6 so for forkjoin api i used here jsr166 library that give you API of java 7 concurrency . alternatively you can use java 7 directly and change the import package accordingly.
2) observe the results by getting the Fibonacci series from 1-10, 1-100, 1-1000, 1-10000,1-100000.
package com.myapp.test;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Scanner;
import org.perf4j.StopWatch;
import jsr166y.forkjoin.ForkJoinPool;
import jsr166y.forkjoin.RecursiveTask;
public class ForkAndJoinExample {
class FibonacciProblem {
public long n;
OutputStream out=null;
public FibonacciProblem(long n) {
this.n = n;
}
public long solve() {
return fibonacci(n);
}
private long fibonacci(long n) {
//System.out.println("Thread: " + Thread.currentThread().getName() + " calculates " + n);
long f1, f2=0, f3=1;
for(int i=1;i<=n;i++){
System.out.print(" "+f3+" ");
f1 = f2;
f2 = f3;
f3 = f1 + f2;
}
return f3;
}
}
//create class by extending RecursiveTask class of jsr166 to use the parallelism feature
class FibonacciTask extends RecursiveTask<Long> {
private static final long THRESHOLD=100000;
private FibonacciProblem problem;
public long result;
public FibonacciTask(FibonacciProblem problem) {
this.problem = problem;
}
@Override
public Long compute() {
if (problem.n <= THRESHOLD) { // easy problem, don't bother with parallelism
result = problem.solve();
}
else {
FibonacciTask worker1 = new FibonacciTask(new FibonacciProblem(problem.n-1));//here i have defined here two worker thread by deviding the probelm in two part
FibonacciTask worker2 = new FibonacciTask(new FibonacciProblem(problem.n-2));
worker1.fork();
result = worker2.compute() + worker1.join();//now i join the result of both of the worker to get the exact result
}
return result;
}
}
public static void main(String[] args) throws IOException {
//taking input from user like 100 or 1000
Scanner scan = new Scanner(System.in);
//writing the result to a file in windows c:\\ drive, file name is result.txt
BufferedWriter out=null;
try {
out=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("c://result.txt")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int input = scan.nextInt();
output("solution1 output", out);
solution1(input,out);
out.newLine();
output("solution2 output", out);
solution2(input,out);
out.flush();
out.close();
}
public static void output(String str,BufferedWriter out)throws IOException{
out.write(str);
out.newLine();
}
private static void solution1(long n,BufferedWriter out)throws IOException{
StopWatch stopWatch = new StopWatch();
ForkAndJoinExample example=new ForkAndJoinExample();
ForkAndJoinExample.FibonacciProblem problem=example.new FibonacciProblem(n);
double result = problem.solve();
stopWatch.stop();
String str= "Computing Fib number: " + n + "\n";
output(str, out);
str="Computed Result: " + result+ "\n";;
output(str, out);
str="Elapsed Time: " + stopWatch.getElapsedTime()+ "\n";;
output(str, out);
}
private static void solution2(long n,BufferedWriter out)throws IOException{
// Check the number of available processors
int processors = Runtime.getRuntime().availableProcessors();
String str="No of processors: " + processors+ "\n";;
output(str, out);
StopWatch stopWatch = new StopWatch();
ForkAndJoinExample example=new ForkAndJoinExample();
ForkAndJoinExample.FibonacciProblem problem=example.new FibonacciProblem(n);
ForkAndJoinExample.FibonacciTask task = example.new FibonacciTask(problem);
ForkJoinPool pool = new ForkJoinPool(processors);//using processor to solve the problem
pool.invoke(task);
double result = task.result;
str="Computed Result: " + result+ "\n";;
output(str, out);
stopWatch.stop();
str="Elapsed Time: " + stopWatch.getElapsedTime()+ "\n";;
output(str, out);
}
}