0

I'm using a singleton class SingletonA for my resources and I have a service ServiceS who uses the resources.

public class SingletonA {
    private static SingletonA ourInstance = new SingletonA();
    public static SingletonA getInstance() { return ourInstance; }
    private SingletonA () {}

    String resources;

    synchronized public void importSomething() {
        resources = "I have some value now";
    }
}

public class ServiceS extends Handler {
    private static ServiceS ourInstance = new ServiceS();
    public static ServiceS getInstance() { return ourInstance; }
    private ServiceS () {}

    SingletonA sa = SingletonA.getInstance();

    public void printResources() {   
        println(sa.resources);
    }
}

public class MyActivity extends Activity {
    SingletonA sa = SingletonA.getInstance();

    @override
    protected void onCreateBundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        sa.importSomthing();            
        ServiceS.printResources();
    }
}

-> In ServicesS class, sa value is null -> sa.printResources() causes NPE

However, since I add one more sa = SingletonA.getInstance(); into ServiceS.printResources() like this:

public void printResources() {   
    sa = SingletonA.getInstance();
    println(sa);
}

-> It worked: sa != null and resources = "I have some value now". Can someone explain for me why sa in ServiceS still null ? Thanks,

Anh-Tuan Mai
  • 1,129
  • 19
  • 36
  • What does `getInstance` look like? And what does `sa.length` look like? – Buddy Aug 12 '15 at 16:34
  • I updated my question, thanks :D – Anh-Tuan Mai Aug 13 '15 at 07:09
  • 1
    I think that it's due to static initialization order. The static `ServiceS.ourService` is initialized before `SingletonA.ourInstance`. – Buddy Aug 13 '15 at 14:54
  • Can you precise the initialization order in context of an simple app with singletons main thread and a timeout thread? Which is the first singleton? When timeout thread can start using the singletons? – Anh-Tuan Mai Aug 14 '15 at 07:57
  • 1
    See [here for more information on static initialization order](http://stackoverflow.com/questions/2007666/in-what-order-do-static-initializer-blocks-in-java-run). But the easy solution would be to just call `SingletonA.getInstance()` when necessary (vs caching in a member variable). Or to lazily initialize `ServiceS.ourInstance` inside `getInstance`. – Buddy Aug 14 '15 at 22:47

1 Answers1

0

As the comment of Buddy:

it's due to static initialization order. The static ServiceS.ourService is initialized before SingletonA.ourInstance.

See here for more information on static initialization order. But the easy solution would be to just call SingletonA.getInstance() when necessary (vs caching in a member variable). Or to lazily initialize ServiceS.ourInstance inside getInstance

Community
  • 1
  • 1
Anh-Tuan Mai
  • 1,129
  • 19
  • 36