Sunday, June 10, 2012

Efficient way to implement singleton pattern in Java


Efficient way to implement singleton pattern in Java?



Source: Tips4all

17 comments:

  1. Use an enum:

    public enum Foo {
    INSTANCE;
    }


    Joshua Bloch explained this approach in his Effective Java Reloaded talk at Google I/O 2008: link to video. Also see slides 30-32 of his presentation (effective_java_reloaded.pdf):


    The Right Way to Implement a Serializable Singleton

    public enum Elvis {
    INSTANCE;
    private final String[] favoriteSongs =
    { "Hound Dog", "Heartbreak Hotel" };
    public void printFavorites() {
    System.out.println(Arrays.toString(favoriteSongs));
    }
    }



    Edit: An online portion of "Effective Java" says:


    "This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton."

    ReplyDelete
  2. Depending on the usage, there are several "correct" answers.

    Since java5 the best way to do it is to use an enum:

    public enum Foo {
    INSTANCE;
    }


    Pre java5, the most simple case is:

    public final class Foo {

    private static final Foo INSTANCE = new Foo();

    private Foo() {
    if (INSTANCE != null) {
    throw new IllegalStateException("Already instantiated");
    }
    }

    public static Foo getInstance() {
    return INSTANCE;
    }
    }


    Let's go over the code. First, you want the class to be final. In this case, I've used the final keyword to let the users know it is final. Then you need to make the constructor private to prevent users to create their own Foo. Throwing an exception from the constructor prevents users to use reflection to create a second Foo. Then you create a private static final Foo field to hold the only instance, and a public static Foo getInstance() method to return it. The Java specification makes sure that the constructor is only called when the class is first used.

    When you have a very large object or heavy construction code AND also have other accessible static methods or fields that might be used before an instance is needed, then and only then you need to use lazy initialization.

    As Bno suggested, you can use a private static class to load the instance. The code would then look like:

    public final class Foo {

    private static class FooLoader {
    private static final Foo INSTANCE = new Foo();
    }

    private Foo() {
    if (FooLoader.INSTANCE != null) {
    throw new IllegalStateException("Already instantiated");
    }
    }

    public static Foo getInstance() {
    return FooLoader.INSTANCE;
    }
    }


    Since the line private static final Foo INSTANCE = new Foo(); is only executed when the class FooLoader is actually used, this takes care of the lazy instantiation, and is it guaranteed to be thread safe.

    When you also want to be able to serialize your object you need to make sure that deserialization won't create a copy.

    public final class Foo implements Serializable {

    private static final long serialVersionUID = 1L;

    private static class FooLoader {
    private static final Foo INSTANCE = new Foo();
    }

    private Foo() {
    if (FooLoader.INSTANCE != null) {
    throw new IllegalStateException("Already instantiated");
    }
    }

    public static Foo getInstance() {
    return FooLoader.INSTANCE;
    }

    @SuppressWarnings("unused")
    private Foo readResolve() {
    return FooLoader.INSTANCE;
    }
    }


    The method readResolve() will make sure the only instance will be returned, even when the object was serialized in a previous run of your program.

    ReplyDelete
  3. The solution posted by Stu Thompson is valid in Java5.0 and later. But I would prefer not to use it because I think it is error prone.

    It's easy to forget the volatile statement and difficult to understand why it is necessary. Without the volatile this code would not be thread safe anymore due to the double-checked locking antipattern. See more about this in paragraph 16.2.4 of Java Concurrency in Practice. In short: This pattern (prior to Java5.0 or without the volatile statement) could return a reference to the Bar object that is (still) in an incorrect state.

    This pattern was invented for performance optimization. But this is really not a real concern anymore. The following lazy initialization code is fast and -more importantly- easier to read.

    class Foo {
    private static class BarHolder {
    public static Bar bar = new Bar();
    }

    public static Bar getBar() {
    return BarHolder.bar;
    }
    }

    ReplyDelete
  4. Thread safe in Java 5+:

    class Foo {
    private static volatile Bar bar = null;
    public static Bar getBar() {
    if (bar == null) {
    synchronized(Foo.class) {
    if (bar == null)
    bar = new Bar();
    }
    }
    return bar;
    }
    }




    EDIT: Pay attention to the volatile modifier here. :) It is important because without it, other threads are not guaranteed by the JMM (Java Memory Model) to see changes to its value. The synchronization does not take care of that--it only serializes access to that block of code.

    EDIT 2:
    @Bno 's answer details the approach recommended by Bill Pugh (FindBugs) and is arguable better. Go read and vote up his answer too.

    ReplyDelete
  5. Make sure that you really need it. Do a google for "singleton anti-pattern" to see some arguments against it. There's nothing inheritantly wrong with it I suppose but it's just a mechanism for exposing some global resource/data so make sure that this is the best way. In particular I've found dependency injection more useful particularly if you are also using unit tests because DI allows you to use mocked resources for testing purposes.

    ReplyDelete
  6. Forget lazy initialization, it's too problematic. This is the simplest solution:

    public class A {

    private static A singleton = new A();

    private A() {}

    public static A getInstance() {
    return singleton;
    }
    }

    ReplyDelete
  7. Don't forget the Singleton is only a Singleton for the Classloader that loaded it. If you are using multiple loaders (Containers) each COULD have its own version of the Singleton.

    ReplyDelete
  8. A classic article on this subject:
    http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

    ReplyDelete
  9. Really consider why you need a singleton before writing it. There is a quasi-religious debate about using them which you can quite easily stumble over if you google singletons in Java.

    Personally I try to avoid singletons as often as possible for many reasons, again most of which can be found by googling singletons. I feel that quite often singletons are abused because they're easy to understand by everybody, they're used as a mechanism for getting "global" data into an OO design and they are used because it is easy to circumvent object lifecycle management (or really thinking about how you can do A from inside B). Look at things like Inversion of Control (IoC) or Dependency Injection (DI) for a nice middleground.

    If you really need one then wikipedia has a good example of a proper implementation of a singleton.

    ReplyDelete
  10. I'm mystified by some of the answers that suggest DI as an alternative to using singletons; these are unrelated concepts. You can use DI to inject either singleton or non-singleton (e.g. per-thread) instances. At least this is true if you use Spring 2.x, I can't speak for other DI frameworks.

    So my answer to the OP would be (in all but the most trivial sample code) to:


    Use a DI framework like Spring, then
    Make it part of your DI configuration whether your dependencies are singletons, request scoped, session scoped, or whatever.


    This approach gives you a nice decoupled (and therefore flexible and testable) architecture where whether to use a singleton is an easily reversible implementation detail (provided any singletons you use are threadsafe, of course).

    ReplyDelete
  11. Nicolas's class is not thread-safe. If two threads, Thread 1 and Thread 2, call getInstance() at the same time, two instances can be created if Thread 1 is pre-empted just after it enters the if block and control is subsequently given to Thread 2.

    ReplyDelete
  12. I use the Spring Framework to manage my singletons. It doesn't enforce the "singleton-ness" of the class (which you can't really do anyway if there are multiple class loaders involved) but provides a really easy way to build and configure different factories for creating different types of objects.

    ReplyDelete
  13. Wikipedia has some examples of singletons, also in Java. The Java 5 implementation looks pretty complete, and is thread-safe (double-checked locking applied).

    ReplyDelete
  14. If you do not need lazy loading then simply try

    public class Singleton {
    private final static Singleton INSTANCE = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() { return Singleton.INSTANCE; }

    protected Object clone() {
    throw new CloneNotSupportedException();
    }
    }


    If you want lazy loading and you want your Singleton to be thread-safe, try the double-checking pattern

    public class Singleton {
    private static Singleton instance = null;

    private Singleton() {}

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

    protected Object clone() {
    throw new CloneNotSupportedException();
    }
    }


    As the double checking pattern is not guaranteed to work (due to some issue with compilers, I don't know anything more about that.), you could also try to synchronize the whole getInstance-method or create a registry for all your Singletons.

    ReplyDelete
  15. Usually find the patterns listed on dofactory.com quite good. Used to use the site quite a bit in University for our Design Patterns class. It may prove useful:

    Useful Link: http://www.dofactory.com/Patterns/PatternSingleton.aspx#_self1

    ReplyDelete
  16. You need double-checking idiom if you need to load the instance variable of a class lazily.
    If you need to load a static variable or a singleton lazily, you need initilization on demand holder idiom.

    In addition, if the singleton needs to be seriliazble, all other fields needs to be transient and readResolve() method needs to be implemented in order to maintain the singleton object invariant. Otherwise, each time the object is deserialized, a new instance of the object will be created. What readResolve() does is replace the new object read by readObject(), which forced that new object to be garbage collected as there is no variable referring to it.

    public static final INSTANCE == ....
    private Object readResolve() {
    return INSTANCE; // original singleton instance.
    }

    ReplyDelete
  17. Sometimes a simple "static Foo foo = new Foo();" is not enough. Just think of some basic data insertion you want to do.

    On the other hand you would have to synchronize any method that instantiates the singleton variable as such. Synchronisation is not bad as such, but it can lead to performance issues or locking (in very very rare situations using this example. The solution is

    public class Singleton {

    private static Singleton instance = null;

    static {
    instance = new Singleton();
    // do some of your instantiation stuff here
    }

    private Singleton() {
    if(instance!=null) {
    throw new ErrorYouWant("Singleton double-instantiation, should never happen!");
    }
    }

    public static getSingleton() {
    return instance;
    }

    }


    Now what happens? The class is loaded via the class loader. Directly after the class was interpreted from a byte Array, the VM executes the static { } - block. that's the whole secret: The static-block is only called once, the time the given class (name) of the given package is loaded by this one class loader.

    ReplyDelete