[英]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.