开发者

Singleton in singleton

I have a singleton in singleton data structure. Currently my implementation is like below:

public class Singleton {
    private Object embInstance;

    private Singleton() { 
        embInstance = new Object();
    }

    private static class SingletonHolder { 
            public static final Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
            return SingletonHolder.instance;
    }

    public Object getEmbInstance() {
        return embInstance;
    }

    public Object resetEmbInstance() {
    开发者_JAVA技巧    embInstance = null;
    }

}

My question are:

  1. Does 'private Singleton()' have to be empty or is it OK to add some code in it?
  2. Is this implementation thread-safe with respect to embInstance?
  3. This implementation is not lazy-loading for embInstance. How to implement a thread-safe lazy-loading for embInstance?

Thanks!


  1. it's ok to add some code to your private, no-args constructor.

  2. I believe the SingletonHolder class will only be initialized once, therefore instance will be guaranteed to be assigned exactly once. However, within the Singleton class you have setters and getters that are not synchronized, so you may have some threading issues there wrt embInstance.

  3. thread-safe lazy-loading: same as lazy-loading, but do it inside a synchronized block:

    public static Object getInstance() {
        if(embInstance == null) {
            synchronized(Singleton.class) {
                if(embInstance == null) {
                    embInstance = new Singleton();
                }
            }
        }
    
        return embInstance;
    }
    

Note that this code is both efficient (no synchronization required once your data is initialized) and thread-safe (initialization occurs inside a synchronized block).

Hope that helps.


The synchronized keyword keeps the methods thread-safe. The getEmbInstance() is the standard way to do lazy instantiation.

public class Singleton {
    private Object embInstance;

    private Singleton() { 
    }

    private static class SingletonHolder { 
            public static final Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
            return SingletonHolder.instance;
    }

    public synchronized Object getEmbInstance() {
        if (embInstance == null)
            embInstance = new Object();
        return embInstance;
    }

    public synchronized Object resetEmbInstance() {
        embInstance = null;
    }
}


  1. Not sure, what you mean. It is certainly syntactically acceptable to have code in the Singleton constructor

  2. This is not inherently thread safe. If embInstance is accessed by multiple threads even if it is via getEmbInstance, it will suffer from race conditions. You must use synchronized to access it if you wish for threadsafety.

  3. To implement a thread-safe lazy load, you must have a lock that prevents changes to Singleton. You can just use the instance of Singleton to lock it as such:

synchronized(this)

Also, you don't need SingletonHolder you can just have a public static Singleton instance in the Singleton class itself.


....eh ...isn't that overcomplexifying things? Why have a singleton in a singleton? Why so many classes?

Moreover, you have a method to 'reset' your singleton to null, but none to actually instantiate a new one.

Why not simply:

public class Singleton {
    private static Singleton instance;

    private Singleton() { }

    public static synchronized Singleton getInstance() {
              if (instance == null)
                     instance = new Singleton(); // The "lazy loading" :p
          return instance;
    }
}


public class A {
    A a;
    private A() {}

    synchronized public static A getOb() {
        if (a == null) {
            a = new A();
        }
        return a;
    }
}

You should use synchronized for thread-safety in Singleton.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜