[英]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.