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),我将每个蚂蚁创建为一个线程,并且当数十个线程(蚂蚁)正在运行时,每隔几圈就会发生上述异常并且线程被杀死。我使用 Random() 的代码是;

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

这段代码写在线程的本地成员函数中。因此,假设每个线程创建数百次随机数并且有十多个线程在工作。

有人可以帮我解决这个例外吗?

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 回答