0
Exception in thread "Thread-8" java.lang.StackOverflowError
    at sun.misc.Unsafe.compareAndSwapLong(Native Method)
    at java.util.concurrent.atomic.AtomicLong.compareAndSet(Unknown Source)
    at java.util.Random.next(Unknown Source)
    at java.util.Random.nextInt(Unknown Source)
        at sim.ant.colony.ants.Forager.moveTo(Forager.java:108)

私はマルチスレッドアプリケーション(Ant Simulation Colony)を使用しており、すべてのantをスレッドとして作成し、数十のスレッド(ant)が実行されている場合、数ターンごとに上記の例外が発生し、スレッドが強制終了されます。Random()を使用しているコードは次のとおりです。

Random rand = new Random();
return adjacents.elementAt(rand.nextInt(8));

このコードは、スレッドのローカルメンバー関数で記述されています。したがって、すべてのスレッドが乱数を数百回作成し、10を超えるスレッドが機能していると仮定します。

誰かがこの例外で私を助けることができますか?

4

1 に答える 1

2

実際にはあなたの問題に対する答えではありませんが、あなたが抱えている問題のより多くの例、それを追跡する方法とそれを修正する方法。

以下のコードを使用してください。

import java.util.HashMap;
import java.util.Map;

public class StackOverflowExample {

    public static void a() {
        Map<String, String> map = new HashMap<String, String>();
        map.putAll(b());

    }

    private static Map<String, String> b() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("a", "a");
        a();
        return map;
    }

    public static void main(String[] args) {
        a();
    }
}

StackOverFlowErrorが即座に生成されます。

Exception in thread "main" java.lang.StackOverflowError
    at java.util.HashMap$Entry.<init>(Unknown Source)
    at java.util.HashMap.addEntry(Unknown Source)
    at java.util.HashMap.put(Unknown Source)
    at StackOverflowExample.b(StackOverflowExample.java:14)

問題はHashMapにもHashMap$Entryにもありません。問題は、a()とb()が、適切な停止条件なしで、つまり無限に、再帰的に相互に呼び出すことです。実際にスタックの下を見ると、すぐにそのパターンがわかります。

Exception in thread "main" java.lang.StackOverflowError
    at java.util.HashMap$Entry.<init>(Unknown Source)
    at java.util.HashMap.addEntry(Unknown Source)
    at java.util.HashMap.put(Unknown Source)
    at StackOverflowExample.b(StackOverflowExample.java:14)
    at StackOverflowExample.a(StackOverflowExample.java:8)
    at StackOverflowExample.b(StackOverflowExample.java:15)
    at StackOverflowExample.a(StackOverflowExample.java:8)
    at StackOverflowExample.b(StackOverflowExample.java:15)
    at StackOverflowExample.a(StackOverflowExample.java:8)
    at StackOverflowExample.b(StackOverflowExample.java:15)
    at StackOverflowExample.a(StackOverflowExample.java:8)
    at StackOverflowExample.b(StackOverflowExample.java:15)
    at StackOverflowExample.a(StackOverflowExample.java:8)
    at StackOverflowExample.b(StackOverflowExample.java:15)
        ...

コードの奥深くにある再帰を見つける必要があります。修正するか、非再帰的な方法に変更してください。

デバッガーを使用すると、各メソッド呼び出しにステップインしてブレークポイントを設定できるため、非常に役立ちます(他の多くの優れた機能の中でも)。

于 2012-05-05T23:44:09.737 に答える