繁体   English   中英

Java中的Stack Overflow异常

[英]Stack Overflow Exception in Java

我是Thread的新手。 我创建了两个名为A和B的类,如下所示 -

public class A {

    private B b;

    public void setB(B b) {
        this.b = b;
    }

    synchronized void foo() {
        b.foo();
        System.out.println("Hi A");
    }
}

public class B {

    private A a;

    public void setA(A a) {
        this.a = a;
    }

    synchronized void foo() {
        a.foo();
        System.out.println("Hi B");
    }
}

现在我创建了另外两个实现Runnable接口的类。

public class AThread implements Runnable{
    private A a;
    public AThread(A a){
        this.a = a;
    }
    @Override
    public void run() {
        a.foo();
    }

}

public class BThread implements Runnable {
    private B b;
    public BThread(B a){
        this.b = b;
    }
    @Override
    public void run() {
        b.foo();
    }

}

在主要方法中,我写了以下代码 -

public static void main(String args[]) {
        A a = new A();
        B b = new B();
        a.setB(b);
        b.setA(a);
        Runnable r1 = new AThread(a);
        Runnable r2 = new BThread(b);
        Thread t1 = new Thread(r1);
        t1.start();

    }

当我运行此代码时,我得到以下异常。

Exception in thread "Thread-0" java.lang.StackOverflowError
    at student.B.foo(B.java:21)
    at student.A.foo(A.java:21)..

任何人都能解释它的原因是什么,我该如何解决?

你有什么期望?

你有一个foo()的方法A调用foo()的方法B调用该foo()的方法A ,依此类推,直到堆栈溢出。

您可以通过避免循环方法调用来解决它。

如果调用函数,则堆栈会保存调用它的函数的地址,并且只有在函数完成后才会删除它。 在A.foo中你打电话给B.foo,在B.foo你打电话给A.foo。 所以你的堆栈充满了B.foo和A.foo的地址。 循环永远不会结束,但堆栈的大小确实如此。 所以我建议尝试消除无限循环。 不能告诉你怎么,因为我不是专家。

正如其他人已经提到的, StackOverflowError与线程无关。 也许一个简单的例子可以使这更清楚。

它可以使用以下代码重现,该代码不包含任何Thread

public static void main(String args[]) {
    A a = new A();
    B b = new B();
    a.setB(b);
    b.setA(a);
    a.foo();
}

A.foo调用B.foo调用A.foo ,最终导致堆栈溢出。 在您的示例t1 ,只涉及一个Thread ,这里是主线程。 你永远不会执行Runnable r2

为了解决您对另一个问题的评论的怀疑
只有当多个线程尝试获取相同的锁时才会发生死锁,并且它不会导致异常 - 通常,死锁的影响是根本没有任何事情发生,锁定的线程永远不会终止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM