In my previous article, we saw how singleton can be created. But there can be some scenarios where serialization and de-serialization of singleton object is required and that can create multiple objects of a singleton class. This can be prevented if we will use enum instead of class for singleton. Note that enum methods are not thread-safe so I used synchronized there. Below is an example, how we can use enum for creating a safe singleton. Date is not thread safe, so I highly recommend returning a copy and replacing the instance with a copy when changes are made.

package com.rpktech.poc;
import java.util.Date;

public enum SingletonWithEnum {
	INSTANCE;	

	private volatile int count;
	private volatile Date date;		

        public int getCount() {	return count;}

	public void setCount(int countParam) { synchronized(this){ count = countParam; }}

	public Date getDate() {  return new Date(date.getTime());}

	public void setDate(Date dateParam) { synchronized(this){ date = (Date) dateParam.clone();}}

	public String printObject() {
		return "Singleton [count=" + getCount() + ", date=" + getDate() + "]";
	}

}

To test it with serialization and de-serialization I have used google’s GSON library.


package com.rpktech.poc;

import java.util.Date;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class TestSingletonWithEnum{
	public static void main(String[] s)
	{
		SingletonWithEnum object1 = SingletonWithEnum.INSTANCE;

		object1.setCount(5);
		object1.setDate(new Date());		

		Gson gson = new GsonBuilder().create();

		SingletonWithEnum object2 = gson.fromJson(gson.toJson(object1), SingletonWithEnum.class);

		object2.setCount(3);

		if(object1 == object2)
			System.out.println("Same");
		else
			System.out.println("Differnent");

		System.out.println(object1.printObject());
		System.out.println(object2.printObject());

	}
}

Output

Same
Singleton [count=3, date=Thu Feb 12 20:39:47 IST 2015]
Singleton [count=3, date=Thu Feb 12 20:39:47 IST 2015]

Enum is good choice for singleton because :

  1. Enum fields will be initialized when INSTANCE is first accessed or when enum is first accessed. So we can achieve lazy initialization functionality by not using INSTANCE until it (singleton object) is required.
  2. You can not extend a proper Singleton since it’s supposed to have a private constructor, so using an enum is fine in place of class (Effective Java Item 2: Enforce the singleton property with a private constructor)
Tagged on:                     

One thought on “Safe Singleton

Leave a Reply

Your email address will not be published.


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>