简体   繁体   中英

Stack Overflow Exception in Java

I am new to Thread. I have created two classes name A and B as follow-

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");
    }
}

Now i have created two other classes which implements Runnable interface.

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();
    }

}

In main method, i have written the following code-

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();

    }

When i am running this code, i got the following exception.

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

Can any one explain what is the route cause of it and how can i solve it?

What did you expect?

You have a foo() method in A calling the foo() method in B that called the foo() method in A , and so on, until the stack overflows.

You can solve it by avoiding circular method calls.

If you call a function, the stack saves the adress of the function it has been called from, and only removes it once the function has been completed. In A.foo you call B.foo, and in B.foo you call A.foo. So your stack fills itself with the adresses of B.foo and A.foo. The loop never ends but the size of your stack does. So i suggest trying to elminate the endless loop. Can't tell you how because I'm not an expert.

As others have already mentioned, the StackOverflowError has nothing to do with threads. Perhaps a simplified example can make this clearer.

It can be reproduced using the following code which does not contain any Thread s:

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

A.foo calls B.foo which calls A.foo which... eventually leads to a stack overflow. There is only a single Thread involved, here the main thread, in your example t1 . You are never executing the Runnable r2 at all.

To address your suspicion from the comments on another question :
A deadlock can only occur if multiple threads try to acquire the same locks, and it would not lead to an Exception - typically, the effect of a deadlock is that nothing happens at all, the locked threads never terminate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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