Home Deadlock in Java Static Initialization of Singleton Classes
Reply: 2

Deadlock in Java Static Initialization of Singleton Classes

Atlian
1#
Atlian Published in 2018-01-13 03:56:44Z

I am designing a game in libgdx, and i decided to make certain manager classes singletons because I noticed that I was often only using one instance of a class, and then passing the same instance to many other classes through constructors, which was very painful to do. Now, I have one manager class that initializes many other classes in it's constructor. I did this by using static block initializers for each class, like so:

public class Example{
    private static Example instance;
    static{
        try{
             synchronized(Example.class){
                 instance = new Example();
             }
           }catch(Exception e){
                 throw new RunTimeException("Failure to initialize Example instance");  
           }
    public static Example getInstance(){
            return instance;
       }  

In the main manager I create an instance of each class through the getInstance method.

The problem that arises is this: say I have static singleton classes Example1 and Example2.
In Example1's constructor I make a variable called:

    example2 = Example2.getInstance();

but because example2 and example1 need to use each other's methods, in Example2's constructor I make:

    example1 = Example1.getInstance();

The problem should be easy to see. Because example1 is waiting for example2 to finish initializing, and example2 needs example1's instance, it ends up creating a deadlock and crashing through the above codes RunTimeException.

this seems easy to fix using just two example classes, but the problem is confounded when I have 6 different singleton manager classes that almost all need to communicate in some way. Easiest solution would obviously not use this methodology, but that would require me to rewrite most of my code.

I can't figure out how to use this methodology of singleton classes without running into this issue, as most of the classes need information from the other classes in the constructor in order to function.
do I remove all of the code from the constructors of the singleton classes, or do something else?

Will Hartung
2#
Will Hartung Reply to 2018-01-13 04:24:37Z

I don't use many singletons any more. I consider a singleton to be a use case, rather than a "type of class", and then rely on something else to manage the "singleton-ness" of it (such as an injection framework). When I don't have one of those, I create a single "singleton" to manage the applications classes-to-be-used-as-singletons.

So, in this case, you can have this class manage the construction and interdependencies for you rather than have the classes manage them for themselves.

public class Singletons {
    private Example1 example1;
    private Example2 example2;
    private Example3 example3;

    private static Singletons instance;

    static {
        Example1 example1 = new Example1();
        Example2 example2 = new Example2();
        Example3 example3 = new Example3();

        instance = new Singletons();

        example1 = new Example1();
        example2 = new Example2();
        example3 = new Example3();

        example1.setExample2(example2);
        example2.setExample3(example3);
        example3.setExample1(example1);

        instance.setExample1(example1);
        instance.setExample2(example2);
        instance.setExample3(example3);
    }

    public Example1 getExample1() {
        return example1;
    }

    private void setExample1(Example1 example1) {
        this.example1 = example1;
    }

    public Example2 getExample2() {
        return example2;
    }

    private void setExample2(Example2 example2) {
        this.example2 = example2;
    }

    public Example3 getExample3() {
        return example3;
    }

    private void setExample3(Example3 example3) {
        this.example3 = example3;
    }

    public Singletons getInstance() {
        return instance;
    }
}
Max Vollmer
3#
Max Vollmer Reply to 2018-01-13 04:20:20Z

It's not a deadlock, it's infinite recursion. There is no way around it, you must refactor your code.

Best thing is not to have any logic in your constructors, just initialization of member variables. Since you don't need to store the singletons as members in your classes, there really should be no need to access them in your constructors. Just use the appropriate getInstance() method to access a singleton from inside the methods of your other singletons.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.396602 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO