簡體   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