Given:



class Sum extends RecursiveAction { //line n1

    static final int THRESHOLD_SIZE = 3;
    int stIndex, lstIndex;
    int[] data;

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

    protected void compute() {
        int sum = 0;
        if (lstIndex - stIndex <= THRESHOLD_SIZE) {
            for (int i = stIndex; i < lstIndex; i++) {
                sum += data[i];
            }
            System.out.println(sum);
        } else {
            new Sum(data, stIndex + THRESHOLD_SIZE, lstIndex).fork();
            new Sum(data, stIndex,
                    Math.min(lstIndex, stIndex + THRESHOLD_SIZE)
            ).compute();
        }
    }
}

and the code fragment:

ForkJoinPool fjPool = new ForkJoinPool();
int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
fjPool.invoke(new Sum(data, 0, data.length));

and given that the sum of all integers from 1 to 10 is 55.

Which statement is true?

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

題解

ForkJoinPool可以將一個大問題拆成很多小問題來進行運算。而RecursiveAction是一種ForkJoinTask,沒有回傳值。

在這個題目中,要利用ForkJoinPool和RecursiveAction來進行整數陣列的元素加總計算。

呼叫ForkJoinPool物件的invoke方法後,會執行RecursiveAction的compute方法,此時stIndex=0、lstIndex=10。程式第15行的判斷式不成立,會再fork出新的Sum物件,用新的執行緒來計算「stIndex=3、lstIndex=10」的部份,而目前的執行緒則重新計算「stIndex=0、lstIndex=3」的部份。

「stIndex=0、lstIndex=3」,會計算sum=1+2+3=6,輸出「6」。

「stIndex=3、lstIndex=10」,會再fork出「stIndex=6、lstIndex=10」,計算「stIndex=3、lstIndex=6」的sum為4+5+6=15,輸出「15」。

「stIndex=6、lstIndex=10」,會再fork出「stIndex=9、lstIndex=10」,計算「stIndex=6、lstIndex=9」的sum為7+8+9=24,輸出「24」。

「stIndex=9、lstIndex=10」,會計算sum=10,輸出「10」。

以上輸出由於是在不同執行緒處理的關係,所以順序不是固定的,但這些輸出的值加總後,即為1加到10的總和「55」。所以答案是選項A。