How to write a Singleton in proper manner? How to write a Singleton in proper manner? multithreading multithreading

How to write a Singleton in proper manner?


The first thing which comes to my mind when creating a singleton is enum. I generally use enum to implement singleton:

enum Singleton {    INSTANCE;}

One benefit you get with using enum is with Serialization.

With singleton class, you would have to make sure that serialization and deserialization doesn't create a new instance by implementing the readResolve() method, while this is not the case with enum.

Using class you should create the singleton like this:

public final class Singleton implements Serializable {    // For lazy-laoding (if only you want)    private static class SingletonHolder {        private static final Singleton INSTANCE = new Singleton();    }    private Singleton() {        if (SingletonHolder.INSTANCE != null) {            // throw Some Exception        }    }    public static Singleton getInstance() {        return SingletonHolder.INSTANCE;    }    // To avoid deserialization create new instance    @SuppressWarnings("unused")    private Singleton readResolve() {        return SingletonHolder.INSTANCE;    }}


Latest Standard Solutions:

  • Core java with Managed Beans / CDI

    @ApplicationScopedpublic class MySingleton { ... }
  • EJB Lite (JEE6)

    @Singletonpublic class MySingleton { ... }

Prior Recommendation (from 'Effective Java 2'):

  • Use an enum, with a single bogus enumeration constant e.g. INSTANCE. Data fields and methods can be either static or non-static (instance) - the two behave equivalently, since there's only one instance

  • Advantages:

    • Yep, it's a singleton. Impossible to create more than one instance by any mechanism (within any given class loader on any JVM).
    • Singleton initialization is thread safe.
  • Disadvantages (compared with above Standard Solutions):

    • The definition is a little obtuse - the 'enum' outer shell could misdirect inexperienced code maintainers. It's a small hack, not the original intention of enum.
    • The implementation leaks through the abstraction. It violates theUniform Access Principle
      • It doesn't work via injection - the client must know it is a singleton & code against the precise enum instance
      • The client must use Singleton.INSTANCE.someMethod()
      • The client can't (simply) code against an interface
      • The client's impacted by design changes between singleton to/from multi-instance objects
    • Extends an ancestor class (Enum), preventing inheritance from other classes
    • Serialization & deserialization just transfer the enum constant name without state - good for technically ensuring there's only one instance, but a null operation with regards to data. In the (rare) event one wanted to share/synchronise singleton state across JVMs/class loaders, replication via serialization couldn't be used.


You can do

public enum Singleton {    INSTANCE;}

and for a utility class which has no instances

public enum Utility {     ;     public static void method();}