package forkJoin;

import chapter8.TakeABreak;
import java.util.concurrent.RecursiveAction;

public class ExampleForkJoin extends RecursiveAction {
//To do Fork and Join our class needs to extend RecursiveAction
    int[] numbers;//array to process
    int pos=0;//current position in the array
    
    //extra information for the Fork Join
    final int threshold = 3;//maximum number of elements in each job will process will be 2
    //final int threshold = 2;//maximum number of elements in each job will process will be 1
    int start,end;//the index numbers this thread is repsonsible for
    
    //Our constructor needs to be able to specify the start and end
    //points for this task
    
    public ExampleForkJoin(int[] numbers,int start,int end){
        this.numbers=numbers;
        this.start=start;
        this.end=end;
    }
    
    //Divide and Conquer...
    protected void compute(){
//        System.out.println("Start Compute. Start: "+start+" End: "+end+" Threshold: "+threshold);
        if ((end-start)<threshold){
            //we have finished dividing up the task so just run it
            processData();
        } else {//divide it up some more
//            System.out.println("Start dividing.");
            int middle = start+(end-start)/2;
            //divide it into two tasks
            //the first task has the first half
            //and the second has the second half
//            System.out.println("Middle is "+middle);
            invokeAll(new ExampleForkJoin(numbers,start,middle),
                      new ExampleForkJoin(numbers,middle,end));
        }
//        System.out.println("End Compute");
    }
   
    //We only need to process from start to finish
    private synchronized void processData(){
        //check to make sure that we haven't reached the end.
//        System.out.println("Start Process Data");
        for (int i=start;i<end;i++)
            System.out.println("Number: "+numbers[i] //Print out i
                               +" Processed by: "
                               +Thread.currentThread().getName());
//        System.out.println("End process Data");
    }
}
