OCP Question 54, Explanation

Given:

class Sum extends RecursiveAction {               //line n1

    static final int THRESHOLD = 3;
    int start, end;
    int[] val;

    public Sum(int[] val, int start, int end) {
        this.val = val;
        this.start = start;
        this.end = end;
    }

    protected void compute() {
        int sum = 0;
        if (end - start <= THRESHOLD) {
            for (int i = start; i < end; i++) {
                sum += val[i];
            }
            System.out.println(sum);
        } else {
            new Sum(val, start + THRESHOLD, end).fork();
            new Sum(val, start,
                    Math.min(end, start + THRESHOLD)
            ).compute();
        }
    }
}

and the code fragment:

ForkJoinPool fjp = new ForkJoinPool();
int val[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
fjp.invoke(new Sum(val, 0, val.length));

and given that the sum of all integers from 11 to 20 is 155.

Which statement is true?

A. The program prints several values that total 155.
B. The program prints 155.
C. A compilation error occurs at line n1.
D. The program prints several values whose sum exceeds 155.

 

The correct answer is A.

 

The RecursiveAction class is abstract, so by extending it the Sum class promises to override RecursiveAction’s abstract protected compute() method, which is exactly what we observe here. Therefore, option C is out.

The logic behind the current Problem’s code is straightforward: we start by creating a ForkJoinPool object, which is a special kind of thread pool specifically designed to support task splitting. Then we invoke() on this object a new task defined in the Sum class. This task is as follows:

  • take a bunch of int values (represented by the val[] array) and see if their number exceeds a certain threshold (in our case it’s three);
  • when the number of values is below the threshold, sum them up and print the result;
  • if, however, their number overshoots the threshold, split the current workload into two subtasks and schedule the upper chunk (that is, from start + THRESHOLD up to end) for execution via the fork() method, and as for the lower chunk, send it to compute() once again.

Following this logic, we can easily predict how many subtasks – and, therefore, lines in the printed output – the code produces: four (workload chunks are {11, 12, 13}, {14, 15, 16}, {17, 18, 19} and, finally {20}). The number of chunks will become five when we add three more elements to the array, and so on.

As for the mysterious invocation of Math.min(), its presence here would’ve been justified if only array indices could be negative. So in our case replacing this call with just start + THRESHOLD works equally well.

Leave Comment

Your email address will not be published.