线程“Thread-8”中的异常java.lang.StackOverflowError ... at java.util.Random.nextInt(Unknown Source)

时间:2012-05-05 23:00:49

标签: java multithreading random synchronization thread-safety

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作为线程,并且当运行数十个线程(蚂蚁)时,在每几次转弯之后发生异常并且线程被杀死。我正在使用Random()的代码是

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

此代码是在线程的本地成员函数中编写的。因此,假设每个线程创建随机数百次,并且有超过10个线程正在工作。

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

1 个答案:

答案 0 :(得分: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)
        ...

您需要找到代码中过于深入的递归。修复它或将其更改为非递归方法。

使用调试器可以对此有很大帮助,因为您可以进入每个方法调用并放置断点(在许多其他好东西中)。