1

背景:我正在模拟逃生恐慌,人们如何逃离房间、建筑物走廊等。对于大量人口,由于每个人都需要计算彼此之间的“社会力量”(即 2000 人),因此需要进行大量计算= 2000^2 次计算)

代码:我尝试实现一个分叉连接机制来拆分这个计算。“人”是“行人”类的数组列表。我的模拟中的每个人都是此类的一个实例。这是我实现 frok/join 的函数:

public static void timeSteppBridgeAllMulti() {
    counterIteration++;
    MultiThreading mt = new MultiThreading(0, people.size());
    ForkJoinPool pool = new ForkJoinPool();
    pool.invoke(mt);

}

static class MultiThreading extends RecursiveAction {

    int mStart = 0;
    int mLength = 0;

    MultiThreading(int start, int length) {
        mStart = start;
        mLength = length;
    }

    protected void computeDirectly() {
        for (int i = mStart; i < mStart + mLength; i++) {
            people.get(i).timeStepBridge();
        }
    }

    @Override
    protected void compute() {
        if (people.size() <= 300) {//do work directly
            computeDirectly();
            return;
        }

        int split = people.size() / 2;
        invokeAll(new MultiThreading(mStart, split), new MultiThreading(mStart + split, people.size()));
    }
}

对于每个人 (people.get(i)),我调用 timeStepBridge 函数,该函数循环遍历所有其他人,读取他们的位置并计算距离和对他们的力。

问题:当人数小于阈值(这里是300)时,程序运行没有问题。但是,当人数超过阈值时,程序会抛出 java.lang.StackOverflowError。我增加了堆栈大小,然后程序只是冻结并且没有响应。

我已经玩了几天,但无法到达任何地方。如果有人有想法,我将不胜感激

4

1 回答 1

1

您错误地将工作拆分为RecursiveAction.

您的RecursiveAction作品使用people长度切片mLength,它根本不应该调用people.size()

@Override
protected void compute() {
    if (mLength <= 300) {//do work directly
        computeDirectly();
        return;
    }

    int split = mLength / 2;
    invokeAll(
        new MultiThreading(mStart, split), 
        new MultiThreading(mStart + split, mLength - split));
}
于 2012-11-27T15:22:19.970 回答