Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with Singleton along with Serialization

Tags:

java

singleton

Consider I have a Singleton class defined as follows.

public class MySingleton implements Serializable{  private static MySingleton myInstance;   private MySingleton(){   }   static{     myInstance =new MySingleton();  }  public static MySingleton getInstance(){     return MySingleton.myInstance;  } } 

The above definition according to me satisfies the requirements of a Singleton.The only additional behaviour added is that the class implements serializable interface.

If another class X get the instance of the single and writes it to a file and at a later point deserializes it to obtain another instance we would have two instances which is against the Singleton principle.

How can I avoid this or am I wrong in above definition itself.

like image 500
frictionlesspulley Avatar asked Oct 14 '10 04:10

frictionlesspulley


People also ask

How do you protect singleton from serialization?

Prevent Singleton Pattern From Deserialization To overcome this issue, we need to override readResolve() method in the Singleton class and return the same Singleton instance.

Can serialization breaks singleton?

Serialization:- Serialization can also cause breakage of singleton property of singleton classes. Serialization is used to convert an object of byte stream and save in a file or send over a network.

How do you handle singleton in multithreading?

Thread Safe Singleton in JavaCreate the private constructor to avoid any new object creation with new operator. Declare a private static instance of the same class. Provide a public static method that will return the singleton class instance variable.

What is the best way to subclass singletons?

I would argue the most common way to implement a singleton is to use an enum with one instance. That might be a "better" way but definitely not the most common way. In all the projects I have worked on, Singletons are implemented as I have shown above.


2 Answers

The best way to do this is to use the enum singleton pattern:

public enum MySingleton {   INSTANCE; } 

This guarantees the singleton-ness of the object and provides serializability for you in such a way that you always get the same instance.

More generally, you can provide a readResolve() method like so:

protected Object readResolve() {   return myInstance; } 
like image 187
ColinD Avatar answered Oct 05 '22 11:10

ColinD


@ColinD is kind of right, but his answer also illustrates why singletons don't really jell with serialization.

Here's what happens when you serialize an enum value (see here).

The rules for serializing an enum instance differ from those for serializing an "ordinary" serializable object: the serialized form of an enum instance consists only of its enum constant name, along with information identifying its base enum type. Deserialization behavior differs as well--the class information is used to find the appropriate enum class, and the Enum.valueOf method is called with that class and the received constant name in order to obtain the enum constant to return.

So any additional state that you attach to your enum values does not survive serialization and deserialization.

You could do the same thing yourself, by adding custom serialization / deserialization code to your singleton classes. That code would need to either not record the singleton's state at all, or throw it away when the singleton is deserialized. Either way, you'd put the logic into a readResolve() method as explained by @ColinD's answer.

Now, I presume that the reason you want to serialize singletons is that you want to persist their state. Unfortunately, that presents a conceptual problem. Suppose that your application has instantiated the singleton in the normal course of events, and then it deserializes some object graph that includes a copy of a previous instance of the singleton. What can it do?

  • If it deserializes the singleton normally, it violates "singleton-ness".
  • If it doesn't then the application cannot access the singleton's previous state.
like image 30
Stephen C Avatar answered Oct 05 '22 10:10

Stephen C