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