Friday, July 13, 2012

Why Enum Singleton are better in Java

Enum Singletons are new way to implement Singleton pattern in Java by using Enum with just one instance. Though Singleton pattern in Java exists from long time Enum Singletons are relatively new concept and in practice from Java 5 onwards after introduction of Enum as keyword and feature. This article is somewhat related to my earlier post on Singleton, 10 interview questions on Singleton pattern in Java where we have discussed common questions asked on interviews about Singleton pattern and 10 Java enum examples, where we have seen how versatile enum can be. This post is about why should we use Enum as Singleton in Java, What benefit it offers compared to conventional singleton methods etc.

Java Enum and Singleton Pattern

Enum Singleton pattern in JavaFollowing are some reasons which make sense to me for using Enum to implement Singleton pattern in Java. By the way If you like articles on design pattern than you can also check my post on Builder design pattern and Decorator design pattern .

1) Enum Singletons are easy to write
This is by far biggest advantage, if you have been writing Singletons prior ot Java 5 than you know that even with double checked locking you can have more than one instances. though that issue is fixed with Java memory model improvement and gurantee provided by volatile variables from Java 5 onwards but it still tricky to write for many beginners. compared to double checked locking with synchronization Enum singletons are cake walk. If you don't believe than just compare below code for conventional singleton with double checked locking and Enum Singletons:

Singleton using Enum in Java
This is the way we generally declare Enum Singleton , it may contain instace variable and instance method but for sake of simplicity I haven’t used any, just beware that if you are using any instance method than you need to ensure thread-safety of that method if at all it affect the state of object. By default creation of Enum instance is thread safe but any other method on Enum is programmers responsibility.

/**
* Singleton pattern example using Java Enumj
*/
public enum EasySingleton{
    INSTANCE;
}

You can acess it by EasySingleton.INSTANCE, much easier than calling getInstance() method on Singleton.

Singleton example with double checked locking
Below code is an example of double checked locking in Singleton pattern, here getInstance() method checks two times to see whether INSTANCE is null or not and that’s why it’s called double checked locking pattern, remember that double checked locking is broker before Java 5 but with the guranteed of volatile variable in Java 5 memory model, it should work perfectly.

/**
* Singleton pattern example with Double checked Locking
*/
public class DoubleCheckedLockingSingleton{
     
private volatile DoubleCheckedLockingSingleton INSTANCE;
 
     
private DoubleCheckedLockingSingleton(){}
 
     
public DoubleCheckedLockingSingleton getInstance(){
         
if(INSTANCE == null){
           
synchronized(DoubleCheckedLockingSingleton.class){
               
//double checking Singleton instance
               
if(INSTANCE == null){
                    INSTANCE
= new DoubleCheckedLockingSingleton();
               
}
           
}
         
}
         
return INSTANCE;
     
}
}

You can call DoubleCheckedLockingSingleton.getInstance() to get access of this Singleton class.

Now Just look at amount of code needed to create a lazy loaded thread-safe Singleton. With Enum Singleton pattern you can have that in one line because creation of Enum instance is thread-safe and guranteed by JVM.

People may argue that there are better way to write Singleton instead of Double checked locking approach but every approach has there own advantages and disadvantages like I mostly prefer static field Singleton intialized during classloading as shwon in below example, but keep in mind that is not a lazy loaded Singleton:

Singleton pattern with static factory method
This is one of my favorite method to impelemnt Singleton pattern in Java, Since Singleton instance is static and final variable it initialized when class is first loaded into memeory so creation of instance is inherently thread-safe.

/**
* Singleton pattern example with static factory method
*/


public class Singleton{
    //initailzed during class loading
    private static final Singleton INSTANCE = new Singleton();
 
    //to prevent creating another instance of Singleton
    private Singleton(){}

    public static Singleton getSingleton(){
        return INSTANCE;
    }
}

You can call Singleton.getSingleton() to get access of this class.


2) Enum Singletons handled Serialization by themselves
Another problem with conventional Singletons are that once you implement serializable interface they are no longer remain Singleton because readObject() method always return a new instance just like constructor in Java. you can avoid that by using readResolve() method and discarding newly created instance by replacing with Singeton as shwon in below example :

    //readResolve to prevent another instance of Singleton
   
private Object readResolve(){
       
return INSTANCE;
   
}

This can become even more complex if your Singleton Class maintain state, as you need to make them transient, but witn Enum Singleton, Serialization is guarnateed by JVM.

3) Creation of Enum instance is thread-safe
As stated in point 1 since creatino of Enum instance is thread-safe by default you don't need to worry about double checked locking.

In summary, given the Serialzation and thraead-safety guaranteed and with couple of line of code enum Singleton pattern is best way to create Singleton in Java 5 world. you can still use other popular methods if you feel so but I still have to find a convincing reason not to use Enum as Singleton, let me know if you got any.

Other Java articles from Javarevisited blog:

16 comments :

Anonymous said...

U have forget the "static" in the "Singleton example with double checked locking" it should be :
public static DoubleCheckedLockingSingleton getInstance(){


also in the first example the enum one to make it like the rest it is more 1:1 to work like the rest the example to become:
public enum Singleton {
INSTANCE;

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

Vineet said...

Thanks for your tutorial dude. I wanted to implement Singleton design pattern using Java enum and looking for an example, didn't know that it would be this easy. you Singleton pattern example with Java Enum is just a piece of cake.

Unknown said...

EnumSingleton or SingletonClassHolder are fine when your singleton's scope == ClassLoader (static). For other cases (lazy singleton per conversation/request/process), the DoubleCheckedSingleton is better.

Anonymous said...

Enums can't extend other enums or classes. And they are final.
Sometimes that's enough not to use such singletons...

bracco23 said...

Enum singleton are perfect as soon as you don't need a singleton that inherit from something. In that case, you cannot use enum anymore and you must use other way...

Michał Niwiński said...

In "Singleton pattern with static factory method" you didn't use factory method pattern but simple factory, which in fact is not "official" pattern.

Anonymous said...

In DoubleCheckedLockingSingleton example, instance variable and getInstance() method must be static. Otherwise, the user has to call object.getInstance() where object is an instantiation of DoubleCheckedLockingSingleton . But the constructor is private; therefore, no one can call getInstance()

Anonymous said...

This is the practical way:

public enum ConnectionManager {
INSTANCE;

private EntityManagerFactory emf;

private ConnectionManagerEnum() {
emf = Persistence.createEntityManagerFactory("cassandra_pu");
}

public EntityManager getEntityManager() {
return emf.createEntityManager();
}
}

Usage: ConnectionManager.INSTANCE.getEntityManager()

Anonymous said...

in last comment, is it ConnectionManagerEnum or ConnectionManager?

KK Sharma said...

we can't have private constructor
private Singleton(){}

Saugat Lama said...

You have to have "static" modifier in both the getInstance() method and volatile variable if you want double checked locking. If method is not static then, you cannot access getInstance by just Singleton.getInstance(), and if the volatile instance variable is not static, then the static getinstance method cannot access the variable.

/**
* Singleton pattern example with Double checked Locking
*/
public class DoubleCheckedLockingSingleton{
private volatile DoubleCheckedLockingSingleton INSTANCE;

private DoubleCheckedLockingSingleton(){}

public DoubleCheckedLockingSingleton getInstance(){
if(INSTANCE == null){
synchronized(DoubleCheckedLockingSingleton.class){
//double checking Singleton instance
if(INSTANCE == null){
INSTANCE = new DoubleCheckedLockingSingleton();
}
}
}
return INSTANCE;
}
}

Anonymous said...

It should be ConnectionManager I guess. Because this method is like constructor, which will be called by Enum while accessed/called.

Aniket Thakur said...

In case of Singleton pattern with static factory method what is the need to declare the Singleton Object as final? If you see java.lang.Runtime class which implements Singleton pattern with early initialization declaration is

private static Runtime currentRuntime = new Runtime();

Yes as in this case object will be created when class is loaded synchronization is not needed. But I do not understand why do we need to declare it as final as you have shown in your example code.

Also as others have mentioned in their comment in your double checked locking you need to declare your getInstance() method as well as the singleton object as static.

Tschoah said...

Hi there,

This is regarding your example under "Singleton example with double checked locking". The method getInstance() first checks if INSTANCE hasn't been initialised yet. If not then it steps into the synchronized block and initialises INSTANCE. I see an issue here.

If two threads access the method getInstance on the same object and thread A stops right after the INSTANCE==null check and thread B now gets the CPU, that thread B will run the same check and then step into the synchronized block where it then initialises INSTANCE. After it will have left the synchronized block thread A gets the CPU back which then steps into the synchronized block where it initialises INSTANCE again. It basically overwrites the value of INSTANCE. Therefore this implementation isn't thread safe.

János Kranczler said...

@Tschoah: When A steps into the synchronized block it will check the INSTANCE for null again.

Anyway the example is bad, because there is no static modifier on the INSTANCE variable and the getInstance() method.

valjok said...

You cannot declare them locally, within a method.

Post a Comment