簡體   English   中英

Java Fork / Join計算0到Integer之間的整數之和.MAX_VALUE導致StackOverflow錯誤

[英]Java Fork/Join computing sum of integers between 0 through Integer.MAX_VALUE leads to StackOverflow error

我將使用一個示例來利用多核CPU體系結構,該示例計算通過Integer.MAX_VALUE得出的所有整數0的總和。 我的門檻是5000000整數。 所以我將其遞歸拆分,直到達到閾值為止。 然后,當達到閾值時,我計算總和。 最后,將所有的總和累加在一起以計算最終結果。 該問題本質上是遞歸的,非常適合Fork / join框架。 但是,當我運行它時,我得到了錯誤。 有時是Stackoverflow錯誤。 其他時間是這樣的。

Exception in thread "ForkJoinPool.commonPool-worker-7" java.lang.NoClassDefFoundError: Could not initialize class java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1198)

這是我的代碼:

public class ParallelSum extends RecursiveTask<Long> {
    private static final int THRESHOLD = 5000000;

    private final int start;
    private final int end;

    public ParallelSum(int start, int end) {
        super();
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        // System.out.println("Start: " + start + " End: " + end);
        if (end - start > THRESHOLD) {
            return ForkJoinTask.invokeAll(createSubtasks()).stream().mapToLong(ForkJoinTask::join).sum();
        }
        return LongStream.rangeClosed(start, end).sum();
    }

    private Collection<RecursiveTask<Long>> createSubtasks() {
        final List<RecursiveTask<Long>> dividedTasks = new ArrayList<>();
        dividedTasks.add(new ParallelSum(start, end / 2));
        dividedTasks.add(new ParallelSum(end / 2 + 1, end));
        return dividedTasks;
    }
}

主要方法是這樣的

public class ParallelSumTest {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        final long sum = new ParallelSum(0, Integer.MAX_VALUE).compute();
        long endTime = System.currentTimeMillis();
        final long elapsedTime = endTime - startTime;
        System.out.println(sum + " was computed in " + elapsedTime + " milliseconds.");
    }
}

這里缺少什么? 我做錯了什么? 任何幫助表示贊賞。

由於JVM耗盡了永久生成空間,很可能引發NoClassDefFoundError異常。 StackOverflowException一樣,這是因為算法生成的遞歸級別太深。

創建任務並將工作分為兩部分時,會出現一個小錯誤。 您應該使用中間索引作為(start + end) / 2而不是end / 2

dividedTasks.add(new ParallelSum(start, (start + end) / 2));
dividedTasks.add(new ParallelSum((start + end) / 2 + 1, end));

在經過上述調整的機器上,我得到以下輸出:

2738188572099084288 was computed in 1636 milliseconds.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM